blob: 972bf2d61879c38710748785058aeefbed7a5d3b [file] [log] [blame]
Andrew de los Reyes0c440052010-08-20 11:25:54 -07001// 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
3// found in the LICENSE file.
4
5#include <string>
6#include <vector>
7#include <gtest/gtest.h>
8#include "base/logging.h"
9#include "update_engine/payload_signer.h"
10#include "update_engine/update_metadata.pb.h"
11#include "update_engine/utils.h"
12
13using std::string;
14using std::vector;
15
16// Note: the test key was generated with the following command:
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -070017// openssl genrsa -out unittest_key.pem 2048
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070018// The public-key version is created by the build system.
Andrew de los Reyes0c440052010-08-20 11:25:54 -070019
Andrew de los Reyes0c440052010-08-20 11:25:54 -070020namespace chromeos_update_engine {
21
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070022const char* kUnittestPrivateKeyPath = "unittest_key.pem";
Darin Petkovd7061ab2010-10-06 14:37:09 -070023const char* kUnittestPublicKeyPath = "unittest_key.pub.pem";
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070024const char* kUnittestPrivateKey2Path = "unittest_key2.pem";
25const char* kUnittestPublicKey2Path = "unittest_key2.pub.pem";
Darin Petkovd7061ab2010-10-06 14:37:09 -070026
27// Some data and its corresponding hash and signature:
28const char kDataToSign[] = "This is some data to sign.";
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -070029
30// Generated by:
31// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
32// hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
Han Shen2643cb72012-06-26 14:45:33 -070033const unsigned char kDataHash[] = {
Darin Petkovd7061ab2010-10-06 14:37:09 -070034 0x7a, 0x07, 0xa6, 0x44, 0x08, 0x86, 0x20, 0xa6,
35 0xc1, 0xf8, 0xd9, 0x02, 0x05, 0x63, 0x0d, 0xb7,
36 0xfc, 0x2b, 0xa0, 0xa9, 0x7c, 0x9d, 0x1d, 0x8c,
37 0x01, 0xf5, 0x78, 0x6d, 0xc5, 0x11, 0xb4, 0x06
38};
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -070039
40// Generated with openssl 1.0, which at the time of this writing, you need
41// to download and install yourself. Here's my command:
42// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
43// ~/local/bin/openssl pkeyutl -sign -inkey unittest_key.pem -pkeyopt
44// digest:sha256 | hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
Han Shen2643cb72012-06-26 14:45:33 -070045const unsigned char kDataSignature[] = {
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -070046 0x9f, 0x86, 0x25, 0x8b, 0xf3, 0xcc, 0xe3, 0x95,
47 0x5f, 0x45, 0x83, 0xb2, 0x66, 0xf0, 0x2a, 0xcf,
48 0xb7, 0xaa, 0x52, 0x25, 0x7a, 0xdd, 0x9d, 0x65,
49 0xe5, 0xd6, 0x02, 0x4b, 0x37, 0x99, 0x53, 0x06,
50 0xc2, 0xc9, 0x37, 0x36, 0x25, 0x62, 0x09, 0x4f,
51 0x6b, 0x22, 0xf8, 0xb3, 0x89, 0x14, 0x98, 0x1a,
52 0xbc, 0x30, 0x90, 0x4a, 0x43, 0xf5, 0xea, 0x2e,
53 0xf0, 0xa4, 0xba, 0xc3, 0xa7, 0xa3, 0x44, 0x70,
54 0xd6, 0xc4, 0x89, 0xd8, 0x45, 0x71, 0xbb, 0xee,
55 0x59, 0x87, 0x3d, 0xd5, 0xe5, 0x40, 0x22, 0x3d,
56 0x73, 0x7e, 0x2a, 0x58, 0x93, 0x8e, 0xcb, 0x9c,
57 0xf2, 0xbb, 0x4a, 0xc9, 0xd2, 0x2c, 0x52, 0x42,
58 0xb0, 0xd1, 0x13, 0x22, 0xa4, 0x78, 0xc7, 0xc6,
59 0x3e, 0xf1, 0xdc, 0x4c, 0x7b, 0x2d, 0x40, 0xda,
60 0x58, 0xac, 0x4a, 0x11, 0x96, 0x3d, 0xa0, 0x01,
61 0xf6, 0x96, 0x74, 0xf6, 0x6c, 0x0c, 0x49, 0x69,
62 0x4e, 0xc1, 0x7e, 0x9f, 0x2a, 0x42, 0xdd, 0x15,
63 0x6b, 0x37, 0x2e, 0x3a, 0xa7, 0xa7, 0x6d, 0x91,
64 0x13, 0xe8, 0x59, 0xde, 0xfe, 0x99, 0x07, 0xd9,
65 0x34, 0x0f, 0x17, 0xb3, 0x05, 0x4c, 0xd2, 0xc6,
66 0x82, 0xb7, 0x38, 0x36, 0x63, 0x1d, 0x9e, 0x21,
67 0xa6, 0x32, 0xef, 0xf1, 0x65, 0xe6, 0xed, 0x95,
68 0x25, 0x9b, 0x61, 0xe0, 0xba, 0x86, 0xa1, 0x7f,
69 0xf8, 0xa5, 0x4a, 0x32, 0x1f, 0x15, 0x20, 0x8a,
70 0x41, 0xc5, 0xb0, 0xd9, 0x4a, 0xda, 0x85, 0xf3,
71 0xdc, 0xa0, 0x98, 0x5d, 0x1d, 0x18, 0x9d, 0x2e,
72 0x42, 0xea, 0x69, 0x13, 0x74, 0x3c, 0x74, 0xf7,
73 0x6d, 0x43, 0xb0, 0x63, 0x90, 0xdb, 0x04, 0xd5,
74 0x05, 0xc9, 0x73, 0x1f, 0x6c, 0xd6, 0xfa, 0x46,
75 0x4e, 0x0f, 0x33, 0x58, 0x5b, 0x0d, 0x1b, 0x55,
76 0x39, 0xb9, 0x0f, 0x43, 0x37, 0xc0, 0x06, 0x0c,
77 0x29, 0x93, 0x43, 0xc7, 0x43, 0xb9, 0xab, 0x7d
Darin Petkovd7061ab2010-10-06 14:37:09 -070078};
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070079
Andrew de los Reyes0c440052010-08-20 11:25:54 -070080//class PayloadSignerTest : public ::testing::Test {};
81
Darin Petkovd7061ab2010-10-06 14:37:09 -070082namespace {
83void SignSampleData(vector<char>* out_signature_blob) {
Andrew de los Reyes0c440052010-08-20 11:25:54 -070084 string data_path;
85 ASSERT_TRUE(
86 utils::MakeTempFile("/tmp/data.XXXXXX", &data_path, NULL));
87 ScopedPathUnlinker data_path_unlinker(data_path);
88 ASSERT_TRUE(utils::WriteFile(data_path.c_str(),
Darin Petkovd7061ab2010-10-06 14:37:09 -070089 kDataToSign,
90 strlen(kDataToSign)));
Andrew de los Reyes0c440052010-08-20 11:25:54 -070091 uint64_t length = 0;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070092 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
93 vector<string> (1, kUnittestPrivateKeyPath),
94 &length));
Andrew de los Reyes0c440052010-08-20 11:25:54 -070095 EXPECT_GT(length, 0);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070096 EXPECT_TRUE(PayloadSigner::SignPayload(
97 data_path,
98 vector<string>(1, kUnittestPrivateKeyPath),
99 out_signature_blob));
Darin Petkovd7061ab2010-10-06 14:37:09 -0700100 EXPECT_EQ(length, out_signature_blob->size());
101}
102}
103
104TEST(PayloadSignerTest, SimpleTest) {
105 vector<char> signature_blob;
106 SignSampleData(&signature_blob);
Andrew de los Reyes0c440052010-08-20 11:25:54 -0700107
108 // Check the signature itself
Andrew de los Reyes0c440052010-08-20 11:25:54 -0700109 Signatures signatures;
110 EXPECT_TRUE(signatures.ParseFromArray(&signature_blob[0],
111 signature_blob.size()));
112 EXPECT_EQ(1, signatures.signatures_size());
113 const Signatures_Signature& signature = signatures.signatures(0);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700114 EXPECT_EQ(kSignatureMessageOriginalVersion, signature.version());
Andrew de los Reyes0c440052010-08-20 11:25:54 -0700115 const string sig_data = signature.data();
Darin Petkovd7061ab2010-10-06 14:37:09 -0700116 ASSERT_EQ(arraysize(kDataSignature), sig_data.size());
117 for (size_t i = 0; i < arraysize(kDataSignature); i++) {
Han Shen2643cb72012-06-26 14:45:33 -0700118 EXPECT_EQ(static_cast<char>(kDataSignature[i]), sig_data[i]);
Darin Petkovd7061ab2010-10-06 14:37:09 -0700119 }
120}
121
Darin Petkovb039d502010-12-03 09:08:04 -0800122TEST(PayloadSignerTest, VerifySignatureTest) {
Darin Petkovd7061ab2010-10-06 14:37:09 -0700123 vector<char> signature_blob;
124 SignSampleData(&signature_blob);
125
126 vector<char> hash_data;
127 EXPECT_TRUE(PayloadSigner::VerifySignature(signature_blob,
128 kUnittestPublicKeyPath,
129 &hash_data));
Han Shen2643cb72012-06-26 14:45:33 -0700130 vector<char> padded_hash_data(reinterpret_cast<const char *>(kDataHash),
131 reinterpret_cast<const char *>(kDataHash +
132 sizeof(kDataHash)));
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700133 PayloadSigner::PadRSA2048SHA256Hash(&padded_hash_data);
134 ASSERT_EQ(padded_hash_data.size(), hash_data.size());
135 for (size_t i = 0; i < padded_hash_data.size(); i++) {
136 EXPECT_EQ(padded_hash_data[i], hash_data[i]);
Andrew de los Reyes0c440052010-08-20 11:25:54 -0700137 }
138}
139
140} // namespace chromeos_update_engine