blob: d6f1e0bb9e23902505b96f8ded5e8c193ffcadfb [file] [log] [blame]
Jed Estep43291862016-02-03 17:02:09 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agree to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <fcntl.h>
19#include <gtest/gtest.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24
25#include <memory>
26#include <string>
27#include <vector>
28
29#include <android-base/stringprintf.h>
30
31#include "common.h"
32#include "mincrypt/sha.h"
33#include "mincrypt/sha256.h"
34#include "minzip/SysUtil.h"
35#include "ui.h"
36#include "verifier.h"
37
38#if defined(__LP64__)
39#define NATIVE_TEST_PATH "/nativetest64"
40#else
41#define NATIVE_TEST_PATH "/nativetest"
42#endif
43
44static const char* DATA_PATH = getenv("ANDROID_DATA");
Jed Estepd5a14c62016-02-05 11:24:27 -080045static const char* TESTDATA_PATH = "/recovery/testdata/";
Jed Estep43291862016-02-03 17:02:09 -080046
47// This is build/target/product/security/testkey.x509.pem after being
48// dumped out by dumpkey.jar.
49RSAPublicKey test_key =
50 { 64, 0xc926ad21,
51 { 0x6afee91fu, 0x7fa31d5bu, 0x38a0b217u, 0x99df9baeu,
52 0xfe72991du, 0x727d3c04u, 0x20943f99u, 0xd08e7826u,
53 0x69e7c8a2u, 0xdeeccc8eu, 0x6b9af76fu, 0x553311c4u,
54 0x07b9e247u, 0x54c8bbcau, 0x6a540d81u, 0x48dbf567u,
55 0x98c92877u, 0x134fbfdeu, 0x01b32564u, 0x24581948u,
56 0x6cddc3b8u, 0x0cd444dau, 0xfe0381ccu, 0xf15818dfu,
57 0xc06e6d42u, 0x2e2f6412u, 0x093a6737u, 0x94d83b31u,
58 0xa466c87au, 0xb3f284a0u, 0xa694ec2cu, 0x053359e6u,
59 0x9717ee6au, 0x0732e080u, 0x220d5008u, 0xdc4af350u,
60 0x93d0a7c3u, 0xe330c9eau, 0xcac3da1eu, 0x8ebecf8fu,
61 0xc2be387fu, 0x38a14e89u, 0x211586f0u, 0x18b846f5u,
62 0x43be4c72u, 0xb578c204u, 0x1bbfb230u, 0xf1e267a8u,
63 0xa2d3e656u, 0x64b8e4feu, 0xe7e83d4bu, 0x3e77a943u,
64 0x3559ffd9u, 0x0ebb0f99u, 0x0aa76ce6u, 0xd3786ea7u,
65 0xbca8cd6bu, 0x068ca8e8u, 0xeb1de2ffu, 0x3e3ecd6cu,
66 0xe0d9d825u, 0xb1edc762u, 0xdec60b24u, 0xd6931904u},
67 { 0xccdcb989u, 0xe19281f9u, 0xa6e80accu, 0xb7f40560u,
68 0x0efb0bccu, 0x7f12b0bbu, 0x1e90531au, 0x136d95d0u,
69 0x9e660665u, 0x7d54918fu, 0xe3b93ea2u, 0x2f415d10u,
70 0x3d2df6e6u, 0x7a627ecfu, 0xa6f22d70u, 0xb995907au,
71 0x09de16b2u, 0xfeb8bd61u, 0xf24ec294u, 0x716a427fu,
72 0x2e12046fu, 0xeaf3d56au, 0xd9b873adu, 0x0ced340bu,
73 0xbc9cec09u, 0x73c65903u, 0xee39ce9bu, 0x3eede25au,
74 0x397633b7u, 0x2583c165u, 0x8514f97du, 0xe9166510u,
75 0x0b6fae99u, 0xa47139fdu, 0xdb8352f0u, 0xb2ad7f2cu,
76 0xa11552e2u, 0xd4d490a7u, 0xe11e8568u, 0xe9e484dau,
77 0xd3ef8449u, 0xa47055dau, 0x4edd9557u, 0x03a78ba1u,
78 0x770e130du, 0x16762facu, 0x0cbdfcc4u, 0xf3070540u,
79 0x008b6515u, 0x60e7e1b7u, 0xa72cf7f9u, 0xaff86e39u,
80 0x4296faadu, 0xfc90430eu, 0x6cc8f377u, 0xb398fd43u,
81 0x423c5997u, 0x991d59c4u, 0x6464bf73u, 0x96431575u,
82 0x15e3d207u, 0x30532a7au, 0x8c4be618u, 0x460a4d76u },
83 3
84 };
85
86RSAPublicKey test_f4_key =
87 { 64, 0xc9bd1f21,
88 { 0x1178db1fu, 0xbf5d0e55u, 0x3393a165u, 0x0ef4c287u,
89 0xbc472a4au, 0x383fc5a1u, 0x4a13b7d2u, 0xb1ff2ac3u,
90 0xaf66b4d9u, 0x9280acefu, 0xa2165bdbu, 0x6a4d6e5cu,
91 0x08ea676bu, 0xb7ac70c7u, 0xcd158139u, 0xa635ccfeu,
92 0xa46ab8a8u, 0x445a3e8bu, 0xdc81d9bbu, 0x91ce1a20u,
93 0x68021cdeu, 0x4516eda9u, 0x8d43c30cu, 0xed1eff14u,
94 0xca387e4cu, 0x58adc233u, 0x4657ab27u, 0xa95b521eu,
95 0xdfc0e30cu, 0x394d64a1u, 0xc6b321a1u, 0x2ca22cb8u,
96 0xb1892d5cu, 0x5d605f3eu, 0x6025483cu, 0x9afd5181u,
97 0x6e1a7105u, 0x03010593u, 0x70acd304u, 0xab957cbfu,
98 0x8844abbbu, 0x53846837u, 0x24e98a43u, 0x2ba060c1u,
99 0x8b88b88eu, 0x44eea405u, 0xb259fc41u, 0x0907ad9cu,
100 0x13003adau, 0xcf79634eu, 0x7d314ec9u, 0xfbbe4c2bu,
101 0xd84d0823u, 0xfd30fd88u, 0x68d8a909u, 0xfb4572d9u,
102 0xa21301c2u, 0xd00a4785u, 0x6862b50cu, 0xcfe49796u,
103 0xdaacbd83u, 0xfb620906u, 0xdf71e0ccu, 0xbbc5b030u },
104 { 0x69a82189u, 0x1a8b22f4u, 0xcf49207bu, 0x68cc056au,
105 0xb206b7d2u, 0x1d449bbdu, 0xe9d342f2u, 0x29daea58u,
106 0xb19d011au, 0xc62f15e4u, 0x9452697au, 0xb62bb87eu,
107 0x60f95cc2u, 0x279ebb2du, 0x17c1efd8u, 0xec47558bu,
108 0xc81334d1u, 0x88fe7601u, 0x79992eb1u, 0xb4555615u,
109 0x2022ac8cu, 0xc79a4b8cu, 0xb288b034u, 0xd6b942f0u,
110 0x0caa32fbu, 0xa065ba51u, 0x4de9f154u, 0x29f64f6cu,
111 0x7910af5eu, 0x3ed4636au, 0xe4c81911u, 0x9183f37du,
112 0x5811e1c4u, 0x29c7a58cu, 0x9715d4d3u, 0xc7e2dce3u,
113 0x140972ebu, 0xf4c8a69eu, 0xa104d424u, 0x5dabbdfbu,
114 0x41cb4c6bu, 0xd7f44717u, 0x61785ff7u, 0x5e0bc273u,
115 0x36426c70u, 0x2aa6f08eu, 0x083badbfu, 0x3cab941bu,
116 0x8871da23u, 0x1ab3dbaeu, 0x7115a21du, 0xf5aa0965u,
117 0xf766f562u, 0x7f110225u, 0x86d96a04u, 0xc50a120eu,
118 0x3a751ca3u, 0xc21aa186u, 0xba7359d0u, 0x3ff2b257u,
119 0xd116e8bbu, 0xfc1318c0u, 0x070e5b1du, 0x83b759a6u },
120 65537
121 };
122
123ECPublicKey test_ec_key =
124 {
125 {
126 {0xd656fa24u, 0x931416cau, 0x1c0278c6u, 0x174ebe4cu,
127 0x6018236au, 0x45ba1656u, 0xe8c05d84u, 0x670ed500u}
128 },
129 {
130 {0x0d179adeu, 0x4c16827du, 0x9f8cb992u, 0x8f69ff8au,
131 0x481b1020u, 0x798d91afu, 0x184db8e9u, 0xb5848dd9u}
132 }
133 };
134
135RecoveryUI* ui = NULL;
136
137class MockUI : public RecoveryUI {
138 void Init() { }
139 void SetStage(int, int) { }
140 void SetLocale(const char*) { }
Tao Baoe1a16af2016-02-04 11:30:42 -0800141 void SetBackground(Icon /*icon*/) { }
Jed Estep43291862016-02-03 17:02:09 -0800142
Tao Baoe1a16af2016-02-04 11:30:42 -0800143 void SetProgressType(ProgressType /*determinate*/) { }
144 void ShowProgress(float /*portion*/, float /*seconds*/) { }
145 void SetProgress(float /*fraction*/) { }
Jed Estep43291862016-02-03 17:02:09 -0800146
Tao Baoe1a16af2016-02-04 11:30:42 -0800147 void ShowText(bool /*visible*/) { }
Jed Estep43291862016-02-03 17:02:09 -0800148 bool IsTextVisible() { return false; }
149 bool WasTextEverVisible() { return false; }
150 void Print(const char* fmt, ...) {
151 va_list ap;
152 va_start(ap, fmt);
153 vfprintf(stderr, fmt, ap);
154 va_end(ap);
155 }
156 void PrintOnScreenOnly(const char* fmt, ...) {
157 va_list ap;
158 va_start(ap, fmt);
159 vfprintf(stderr, fmt, ap);
160 va_end(ap);
161 }
162 void ShowFile(const char*) { }
163
Tao Baoe1a16af2016-02-04 11:30:42 -0800164 void StartMenu(const char* const* /*headers*/,
165 const char* const* /*items*/,
166 int /*initial_selection*/) { }
167 int SelectMenu(int /*sel*/) { return 0; }
Jed Estep43291862016-02-03 17:02:09 -0800168 void EndMenu() { }
169};
170
171void
172ui_print(const char* format, ...) {
173 va_list ap;
174 va_start(ap, format);
175 vfprintf(stdout, format, ap);
176 va_end(ap);
177}
178
179class VerifierTest : public testing::TestWithParam<std::vector<std::string>> {
180 public:
181 MemMapping memmap;
182 std::vector<Certificate> certs;
183
184 virtual void SetUp() {
185 std::vector<std::string> args = GetParam();
186 std::string package = android::base::StringPrintf("%s%s%s%s", DATA_PATH, NATIVE_TEST_PATH,
187 TESTDATA_PATH, args[0].c_str());
188 for (auto it = ++(args.cbegin()); it != args.cend(); ++it) {
189 if (it->substr(it->length() - 3, it->length()) == "256") {
190 if (certs.empty()) {
191 FAIL() << "May only specify -sha256 after key type\n";
192 }
193 certs.back().hash_len = SHA256_DIGEST_SIZE;
194 } else if (*it == "ec") {
195 certs.emplace_back(SHA_DIGEST_SIZE, Certificate::EC,
196 nullptr, std::unique_ptr<ECPublicKey>(new ECPublicKey(test_ec_key)));
197 } else if (*it == "e3") {
198 certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA,
199 std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_key)), nullptr);
200 } else if (*it == "f4") {
201 certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA,
202 std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_f4_key)), nullptr);
203 }
204 }
205 if (certs.empty()) {
206 certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA,
207 std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_key)), nullptr);
208 }
209 if (sysMapFile(package.c_str(), &memmap) != 0) {
210 FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n";
211 }
212 }
213
214 static void SetUpTestCase() {
215 ui = new MockUI();
216 }
217};
218
219class VerifierSuccessTest : public VerifierTest {
220};
221
222class VerifierFailureTest : public VerifierTest {
223};
224
225TEST_P(VerifierSuccessTest, VerifySucceed) {
226 ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_SUCCESS);
227}
228
229TEST_P(VerifierFailureTest, VerifyFailure) {
230 ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_FAILURE);
231}
232
233INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest,
234 ::testing::Values(
235 std::vector<std::string>({"otasigned.zip", "e3"}),
236 std::vector<std::string>({"otasigned_f4.zip", "f4"}),
237 std::vector<std::string>({"otasigned_sha256.zip", "e3", "sha256"}),
238 std::vector<std::string>({"otasigned_f4_sha256.zip", "f4", "sha256"}),
239 std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "ec", "sha256"})));
240
241INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest,
242 ::testing::Values(
243 std::vector<std::string>({"otasigned.zip", "f4", "e3"}),
244 std::vector<std::string>({"otasigned_f4.zip", "ec", "f4"}),
245 std::vector<std::string>({"otasigned_sha256.zip", "ec", "e3", "e3", "sha256"}),
246 std::vector<std::string>({"otasigned_f4_sha256.zip", "ec", "sha256", "e3", "f4", "sha256"}),
247 std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "f4", "sha256", "e3", "ec", "sha256"})));
248
249INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest,
250 ::testing::Values(
251 std::vector<std::string>({"otasigned.zip", "f4"}),
252 std::vector<std::string>({"otasigned_f4.zip", "e3"}),
253 std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "e3", "sha256"})));
254
255INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest,
256 ::testing::Values(
257 std::vector<std::string>({"otasigned.zip", "e3", "sha256"}),
258 std::vector<std::string>({"otasigned_f4.zip", "f4", "sha256"}),
259 std::vector<std::string>({"otasigned_sha256.zip"}),
260 std::vector<std::string>({"otasigned_f4_sha256.zip", "f4"}),
261 std::vector<std::string>({"otasigned_ecdsa_sha256.zip"})));
262
263INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest,
264 ::testing::Values(
265 std::vector<std::string>({"random.zip"}),
266 std::vector<std::string>({"fake-eocd.zip"}),
267 std::vector<std::string>({"alter-metadata.zip"}),
268 std::vector<std::string>({"alter-footer.zip"})));