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

Side by Side Diff: payload_signer.cc

Issue 6771024: AU: Switch to 2048 bit RSA keys; Pad SHA256 hashes appropriately. (Closed) Base URL: http://git.chromium.org/git/update_engine.git@master
Patch Set: remove debug log statement Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 "update_engine/payload_signer.h" 5 #include "update_engine/payload_signer.h"
6 6
7 #include <base/logging.h> 7 #include <base/logging.h>
8 #include <base/string_util.h> 8 #include <base/string_util.h>
9 #include <openssl/pem.h> 9 #include <openssl/pem.h>
10 10
11 #include "update_engine/delta_diff_generator.h" 11 #include "update_engine/delta_diff_generator.h"
12 #include "update_engine/delta_performer.h" 12 #include "update_engine/delta_performer.h"
13 #include "update_engine/omaha_hash_calculator.h" 13 #include "update_engine/omaha_hash_calculator.h"
14 #include "update_engine/subprocess.h" 14 #include "update_engine/subprocess.h"
15 #include "update_engine/update_metadata.pb.h" 15 #include "update_engine/update_metadata.pb.h"
16 #include "update_engine/utils.h" 16 #include "update_engine/utils.h"
17 17
18 using std::string; 18 using std::string;
19 using std::vector; 19 using std::vector;
20 20
21 namespace chromeos_update_engine { 21 namespace chromeos_update_engine {
22 22
23 const uint32_t kSignatureMessageVersion = 1; 23 const uint32_t kSignatureMessageVersion = 1;
24 24
25 namespace { 25 namespace {
26
27 const char kRSA2048SHA256Padding[] = {
28 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
29 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
30 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
31 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
32 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
33 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
34 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
36 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
44 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
45 0x00, 0x04, 0x20
46 };
47
26 // Given a raw |signature|, packs it into a protobuf and serializes it into a 48 // Given a raw |signature|, packs it into a protobuf and serializes it into a
27 // binary blob. Returns true on success, false otherwise. 49 // binary blob. Returns true on success, false otherwise.
28 bool ConvertSignatureToProtobufBlob(const vector<char> signature, 50 bool ConvertSignatureToProtobufBlob(const vector<char> signature,
29 vector<char>* out_signature_blob) { 51 vector<char>* out_signature_blob) {
30 // Pack it into a protobuf 52 // Pack it into a protobuf
31 Signatures out_message; 53 Signatures out_message;
32 Signatures_Signature* sig_message = out_message.add_signatures(); 54 Signatures_Signature* sig_message = out_message.add_signatures();
33 sig_message->set_version(kSignatureMessageVersion); 55 sig_message->set_version(kSignatureMessageVersion);
34 sig_message->set_data(signature.data(), signature.size()); 56 sig_message->set_data(signature.data(), signature.size());
35 57
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 vector<char>* out_signature) { 128 vector<char>* out_signature) {
107 string sig_path; 129 string sig_path;
108 TEST_AND_RETURN_FALSE( 130 TEST_AND_RETURN_FALSE(
109 utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_path, NULL)); 131 utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_path, NULL));
110 ScopedPathUnlinker sig_path_unlinker(sig_path); 132 ScopedPathUnlinker sig_path_unlinker(sig_path);
111 133
112 string hash_path; 134 string hash_path;
113 TEST_AND_RETURN_FALSE( 135 TEST_AND_RETURN_FALSE(
114 utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_path, NULL)); 136 utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_path, NULL));
115 ScopedPathUnlinker hash_path_unlinker(hash_path); 137 ScopedPathUnlinker hash_path_unlinker(hash_path);
138 // We expect unpadded SHA256 hash coming in
139 vector<char> padded_hash(hash);
gauravsh 2011/03/29 23:04:50 should you check here that this is indeed the size
adlr 2011/03/30 19:40:14 Done.
140 PadRSA2048SHA256Hash(&padded_hash);
116 TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(), 141 TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
117 hash.data(), 142 padded_hash.data(),
118 hash.size())); 143 padded_hash.size()));
119 144
120 // This runs on the server, so it's okay to cop out and call openssl 145 // This runs on the server, so it's okay to cop out and call openssl
121 // executable rather than properly use the library 146 // executable rather than properly use the library
122 vector<string> cmd; 147 vector<string> cmd;
123 SplitString("/usr/bin/openssl rsautl -pkcs -sign -inkey x -in x -out x", 148 SplitString("/usr/bin/openssl rsautl -raw -sign -inkey x -in x -out x",
124 ' ', 149 ' ',
125 &cmd); 150 &cmd);
126 cmd[cmd.size() - 5] = private_key_path; 151 cmd[cmd.size() - 5] = private_key_path;
127 cmd[cmd.size() - 3] = hash_path; 152 cmd[cmd.size() - 3] = hash_path;
128 cmd[cmd.size() - 1] = sig_path; 153 cmd[cmd.size() - 1] = sig_path;
129 154
130 int return_code = 0; 155 int return_code = 0;
131 TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &return_code)); 156 TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &return_code));
132 TEST_AND_RETURN_FALSE(return_code == 0); 157 TEST_AND_RETURN_FALSE(return_code == 0);
133 158
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 return false; 238 return false;
214 } 239 }
215 240
216 // Decrypts the signature. 241 // Decrypts the signature.
217 vector<char> hash_data(keysize); 242 vector<char> hash_data(keysize);
218 int decrypt_size = RSA_public_decrypt( 243 int decrypt_size = RSA_public_decrypt(
219 sig_data.size(), 244 sig_data.size(),
220 reinterpret_cast<const unsigned char*>(sig_data.data()), 245 reinterpret_cast<const unsigned char*>(sig_data.data()),
221 reinterpret_cast<unsigned char*>(hash_data.data()), 246 reinterpret_cast<unsigned char*>(hash_data.data()),
222 rsa, 247 rsa,
223 RSA_PKCS1_PADDING); 248 RSA_NO_PADDING);
224 RSA_free(rsa); 249 RSA_free(rsa);
225 TEST_AND_RETURN_FALSE(decrypt_size > 0 && 250 TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
226 decrypt_size <= static_cast<int>(hash_data.size())); 251 decrypt_size <= static_cast<int>(hash_data.size()));
227 hash_data.resize(decrypt_size); 252 hash_data.resize(decrypt_size);
228 out_hash_data->swap(hash_data); 253 out_hash_data->swap(hash_data);
229 return true; 254 return true;
230 } 255 }
231 256
232 bool PayloadSigner::VerifySignedPayload(const std::string& payload_path, 257 bool PayloadSigner::VerifySignedPayload(const std::string& payload_path,
233 const std::string& public_key_path) { 258 const std::string& public_key_path) {
(...skipping 10 matching lines...) Expand all
244 vector<char> signature_blob( 269 vector<char> signature_blob(
245 payload.begin() + metadata_size + manifest.signatures_offset(), 270 payload.begin() + metadata_size + manifest.signatures_offset(),
246 payload.end()); 271 payload.end());
247 vector<char> signed_hash; 272 vector<char> signed_hash;
248 TEST_AND_RETURN_FALSE(VerifySignature( 273 TEST_AND_RETURN_FALSE(VerifySignature(
249 signature_blob, public_key_path, &signed_hash)); 274 signature_blob, public_key_path, &signed_hash));
250 TEST_AND_RETURN_FALSE(!signed_hash.empty()); 275 TEST_AND_RETURN_FALSE(!signed_hash.empty());
251 vector<char> hash; 276 vector<char> hash;
252 TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes( 277 TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
253 payload.data(), metadata_size + manifest.signatures_offset(), &hash)); 278 payload.data(), metadata_size + manifest.signatures_offset(), &hash));
279 PadRSA2048SHA256Hash(&hash);
254 TEST_AND_RETURN_FALSE(hash == signed_hash); 280 TEST_AND_RETURN_FALSE(hash == signed_hash);
255 return true; 281 return true;
256 } 282 }
257 283
258 bool PayloadSigner::HashPayloadForSigning(const std::string& payload_path, 284 bool PayloadSigner::HashPayloadForSigning(const std::string& payload_path,
259 int signature_size, 285 int signature_size,
260 vector<char>* out_hash_data) { 286 vector<char>* out_hash_data) {
261 // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory. 287 // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory.
262 288
263 // Loads the payload and adds the signature op to it. 289 // Loads the payload and adds the signature op to it.
(...skipping 28 matching lines...) Expand all
292 // Appends the signature blob to the end of the payload and writes the new 318 // Appends the signature blob to the end of the payload and writes the new
293 // payload. 319 // payload.
294 payload.insert(payload.end(), signature_blob.begin(), signature_blob.end()); 320 payload.insert(payload.end(), signature_blob.begin(), signature_blob.end());
295 LOG(INFO) << "Signed payload size: " << payload.size(); 321 LOG(INFO) << "Signed payload size: " << payload.size();
296 TEST_AND_RETURN_FALSE(utils::WriteFile(signed_payload_path.c_str(), 322 TEST_AND_RETURN_FALSE(utils::WriteFile(signed_payload_path.c_str(),
297 payload.data(), 323 payload.data(),
298 payload.size())); 324 payload.size()));
299 return true; 325 return true;
300 } 326 }
301 327
328 bool PayloadSigner::PadRSA2048SHA256Hash(std::vector<char>* hash) {
329 TEST_AND_RETURN_FALSE(hash->size() == 32);
330 hash->insert(hash->begin(),
331 kRSA2048SHA256Padding,
332 kRSA2048SHA256Padding + sizeof(kRSA2048SHA256Padding));
333 TEST_AND_RETURN_FALSE(hash->size() == 256);
334 return true;
335 }
336
302 } // namespace chromeos_update_engine 337 } // namespace chromeos_update_engine
OLDNEW
« payload_signer.h ('K') | « payload_signer.h ('k') | payload_signer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698