1 /* 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 <stdio.h> 20 #include <stdlib.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 24 #include <string> 25 #include <vector> 26 27 #include <android-base/file.h> 28 #include <android-base/stringprintf.h> 29 #include <android-base/strings.h> 30 #include <android-base/unique_fd.h> 31 #include <gtest/gtest.h> 32 #include <openssl/bn.h> 33 #include <openssl/ec.h> 34 #include <openssl/nid.h> 35 #include <ziparchive/zip_writer.h> 36 37 #include "common/test_constants.h" 38 #include "install/package.h" 39 #include "install/verifier.h" 40 #include "otautil/sysutil.h" 41 42 using namespace std::string_literals; 43 44 static void LoadKeyFromFile(const std::string& file_name, Certificate* cert) { 45 std::string testkey_string; 46 ASSERT_TRUE(android::base::ReadFileToString(file_name, &testkey_string)); 47 ASSERT_TRUE(LoadCertificateFromBuffer( 48 std::vector<uint8_t>(testkey_string.begin(), testkey_string.end()), cert)); 49 } 50 51 static void VerifyFile(const std::string& content, const std::vector<Certificate>& keys, 52 int expected) { 53 auto package = 54 Package::CreateMemoryPackage(std::vector<uint8_t>(content.begin(), content.end()), nullptr); 55 ASSERT_NE(nullptr, package); 56 57 ASSERT_EQ(expected, verify_file(package.get(), keys)); 58 } 59 60 static void VerifyPackageWithCertificates(const std::string& name, 61 const std::vector<Certificate>& certs) { 62 std::string path = from_testdata_base(name); 63 auto package = Package::CreateMemoryPackage(path, nullptr); 64 ASSERT_NE(nullptr, package); 65 66 ASSERT_EQ(VERIFY_SUCCESS, verify_file(package.get(), certs)); 67 } 68 69 static void VerifyPackageWithSingleCertificate(const std::string& name, Certificate&& cert) { 70 std::vector<Certificate> certs; 71 certs.emplace_back(std::move(cert)); 72 VerifyPackageWithCertificates(name, certs); 73 } 74 75 static void BuildCertificateArchive(const std::vector<std::string>& file_names, int fd) { 76 FILE* zip_file_ptr = fdopen(fd, "wb"); 77 ZipWriter zip_writer(zip_file_ptr); 78 79 for (const auto& name : file_names) { 80 std::string content; 81 ASSERT_TRUE(android::base::ReadFileToString(name, &content)); 82 83 // Makes sure the zip entry name has the correct suffix. 84 std::string entry_name = name; 85 if (!android::base::EndsWith(entry_name, "x509.pem")) { 86 entry_name += "x509.pem"; 87 } 88 ASSERT_EQ(0, zip_writer.StartEntry(entry_name.c_str(), ZipWriter::kCompress)); 89 ASSERT_EQ(0, zip_writer.WriteBytes(content.data(), content.size())); 90 ASSERT_EQ(0, zip_writer.FinishEntry()); 91 } 92 93 ASSERT_EQ(0, zip_writer.Finish()); 94 ASSERT_EQ(0, fclose(zip_file_ptr)); 95 } 96 97 TEST(VerifierTest, LoadCertificateFromBuffer_failure) { 98 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 99 std::string testkey_string; 100 ASSERT_TRUE( 101 android::base::ReadFileToString(from_testdata_base("testkey_v1.txt"), &testkey_string)); 102 ASSERT_FALSE(LoadCertificateFromBuffer( 103 std::vector<uint8_t>(testkey_string.begin(), testkey_string.end()), &cert)); 104 } 105 106 TEST(VerifierTest, LoadCertificateFromBuffer_sha1_exponent3) { 107 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 108 LoadKeyFromFile(from_testdata_base("testkey_v1.x509.pem"), &cert); 109 110 ASSERT_EQ(SHA_DIGEST_LENGTH, cert.hash_len); 111 ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type); 112 ASSERT_EQ(nullptr, cert.ec); 113 114 VerifyPackageWithSingleCertificate("otasigned_v1.zip", std::move(cert)); 115 } 116 117 TEST(VerifierTest, LoadCertificateFromBuffer_sha1_exponent65537) { 118 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 119 LoadKeyFromFile(from_testdata_base("testkey_v2.x509.pem"), &cert); 120 121 ASSERT_EQ(SHA_DIGEST_LENGTH, cert.hash_len); 122 ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type); 123 ASSERT_EQ(nullptr, cert.ec); 124 125 VerifyPackageWithSingleCertificate("otasigned_v2.zip", std::move(cert)); 126 } 127 128 TEST(VerifierTest, LoadCertificateFromBuffer_sha256_exponent3) { 129 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 130 LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &cert); 131 132 ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len); 133 ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type); 134 ASSERT_EQ(nullptr, cert.ec); 135 136 VerifyPackageWithSingleCertificate("otasigned_v3.zip", std::move(cert)); 137 } 138 139 TEST(VerifierTest, LoadCertificateFromBuffer_sha256_exponent65537) { 140 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 141 LoadKeyFromFile(from_testdata_base("testkey_v4.x509.pem"), &cert); 142 143 ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len); 144 ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type); 145 ASSERT_EQ(nullptr, cert.ec); 146 147 VerifyPackageWithSingleCertificate("otasigned_v4.zip", std::move(cert)); 148 } 149 150 TEST(VerifierTest, LoadCertificateFromBuffer_sha256_ec256bits) { 151 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 152 LoadKeyFromFile(from_testdata_base("testkey_v5.x509.pem"), &cert); 153 154 ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len); 155 ASSERT_EQ(Certificate::KEY_TYPE_EC, cert.key_type); 156 ASSERT_EQ(nullptr, cert.rsa); 157 158 VerifyPackageWithSingleCertificate("otasigned_v5.zip", std::move(cert)); 159 } 160 161 TEST(VerifierTest, LoadCertificateFromBuffer_sha256_rsa4096_bits) { 162 Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 163 LoadKeyFromFile(from_testdata_base("testkey_4096bits.x509.pem"), &cert); 164 165 ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len); 166 ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type); 167 ASSERT_EQ(nullptr, cert.ec); 168 169 VerifyPackageWithSingleCertificate("otasigned_4096bits.zip", std::move(cert)); 170 } 171 172 TEST(VerifierTest, LoadCertificateFromBuffer_check_rsa_keys) { 173 std::unique_ptr<RSA, RSADeleter> rsa(RSA_new()); 174 std::unique_ptr<BIGNUM, decltype(&BN_free)> exponent(BN_new(), BN_free); 175 BN_set_word(exponent.get(), 3); 176 RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr); 177 ASSERT_TRUE(CheckRSAKey(rsa)); 178 179 // Exponent is expected to be 3 or 65537 180 BN_set_word(exponent.get(), 17); 181 RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr); 182 ASSERT_FALSE(CheckRSAKey(rsa)); 183 184 // Modulus is expected to be 2048. 185 BN_set_word(exponent.get(), 3); 186 RSA_generate_key_ex(rsa.get(), 1024, exponent.get(), nullptr); 187 ASSERT_FALSE(CheckRSAKey(rsa)); 188 } 189 190 TEST(VerifierTest, LoadCertificateFromBuffer_check_ec_keys) { 191 std::unique_ptr<EC_KEY, ECKEYDeleter> ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); 192 ASSERT_EQ(1, EC_KEY_generate_key(ec.get())); 193 ASSERT_TRUE(CheckECKey(ec)); 194 195 // Expects 256-bit EC key with curve NIST P-256 196 ec.reset(EC_KEY_new_by_curve_name(NID_secp224r1)); 197 ASSERT_EQ(1, EC_KEY_generate_key(ec.get())); 198 ASSERT_FALSE(CheckECKey(ec)); 199 } 200 201 TEST(VerifierTest, LoadKeysFromZipfile_empty_archive) { 202 TemporaryFile otacerts; 203 BuildCertificateArchive({}, otacerts.release()); 204 std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path); 205 ASSERT_TRUE(certs.empty()); 206 } 207 208 TEST(VerifierTest, LoadKeysFromZipfile_single_key) { 209 TemporaryFile otacerts; 210 BuildCertificateArchive({ from_testdata_base("testkey_v1.x509.pem") }, otacerts.release()); 211 std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path); 212 ASSERT_EQ(1, certs.size()); 213 214 VerifyPackageWithCertificates("otasigned_v1.zip", certs); 215 } 216 217 TEST(VerifierTest, LoadKeysFromZipfile_corrupted_key) { 218 TemporaryFile corrupted_key; 219 std::string content; 220 ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("testkey_v1.x509.pem"), &content)); 221 content = "random-contents" + content; 222 ASSERT_TRUE(android::base::WriteStringToFd(content, corrupted_key.release())); 223 224 TemporaryFile otacerts; 225 BuildCertificateArchive({ from_testdata_base("testkey_v2.x509.pem"), corrupted_key.path }, 226 otacerts.release()); 227 std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path); 228 ASSERT_EQ(0, certs.size()); 229 } 230 231 TEST(VerifierTest, LoadKeysFromZipfile_multiple_key) { 232 TemporaryFile otacerts; 233 BuildCertificateArchive( 234 { 235 from_testdata_base("testkey_v3.x509.pem"), 236 from_testdata_base("testkey_v4.x509.pem"), 237 from_testdata_base("testkey_v5.x509.pem"), 238 239 }, 240 otacerts.release()); 241 std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path); 242 ASSERT_EQ(3, certs.size()); 243 244 VerifyPackageWithCertificates("otasigned_v3.zip", certs); 245 VerifyPackageWithCertificates("otasigned_v4.zip", certs); 246 VerifyPackageWithCertificates("otasigned_v5.zip", certs); 247 } 248 249 class VerifierTest : public testing::TestWithParam<std::vector<std::string>> { 250 protected: 251 void SetUp() override { 252 std::vector<std::string> args = GetParam(); 253 std::string path = from_testdata_base(args[0]); 254 memory_package_ = Package::CreateMemoryPackage(path, nullptr); 255 ASSERT_NE(nullptr, memory_package_); 256 file_package_ = Package::CreateFilePackage(path, nullptr); 257 ASSERT_NE(nullptr, file_package_); 258 259 for (auto it = ++args.cbegin(); it != args.cend(); ++it) { 260 std::string public_key_file = from_testdata_base("testkey_" + *it + ".x509.pem"); 261 certs_.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 262 LoadKeyFromFile(public_key_file, &certs_.back()); 263 } 264 } 265 266 std::unique_ptr<Package> memory_package_; 267 std::unique_ptr<Package> file_package_; 268 std::vector<Certificate> certs_; 269 }; 270 271 class VerifierSuccessTest : public VerifierTest { 272 }; 273 274 class VerifierFailureTest : public VerifierTest { 275 }; 276 277 TEST(VerifierTest, BadPackage_AlteredFooter) { 278 std::vector<Certificate> certs; 279 certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 280 LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back()); 281 282 std::string package; 283 ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("otasigned_v3.zip"), &package)); 284 ASSERT_EQ(std::string("\xc0\x06\xff\xff\xd2\x06", 6), package.substr(package.size() - 6, 6)); 285 286 // Alter the footer. 287 package[package.size() - 5] = '\x05'; 288 VerifyFile(package, certs, VERIFY_FAILURE); 289 } 290 291 TEST(VerifierTest, BadPackage_AlteredContent) { 292 std::vector<Certificate> certs; 293 certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 294 LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back()); 295 296 std::string package; 297 ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("otasigned_v3.zip"), &package)); 298 ASSERT_GT(package.size(), static_cast<size_t>(100)); 299 300 // Alter the content. 301 std::string altered1(package); 302 altered1[50] += 1; 303 VerifyFile(altered1, certs, VERIFY_FAILURE); 304 305 std::string altered2(package); 306 altered2[10] += 1; 307 VerifyFile(altered2, certs, VERIFY_FAILURE); 308 } 309 310 TEST(VerifierTest, BadPackage_SignatureStartOutOfBounds) { 311 std::vector<Certificate> certs; 312 certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr); 313 LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back()); 314 315 // Signature start is 65535 (0xffff) while comment size is 0 (Bug: 31914369). 316 std::string package = "\x50\x4b\x05\x06"s + std::string(12, '\0') + "\xff\xff\xff\xff\x00\x00"s; 317 VerifyFile(package, certs, VERIFY_FAILURE); 318 } 319 320 TEST_P(VerifierSuccessTest, VerifySucceed) { 321 ASSERT_EQ(VERIFY_SUCCESS, verify_file(memory_package_.get(), certs_)); 322 ASSERT_EQ(VERIFY_SUCCESS, verify_file(file_package_.get(), certs_)); 323 } 324 325 TEST_P(VerifierFailureTest, VerifyFailure) { 326 ASSERT_EQ(VERIFY_FAILURE, verify_file(memory_package_.get(), certs_)); 327 ASSERT_EQ(VERIFY_FAILURE, verify_file(file_package_.get(), certs_)); 328 } 329 330 INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest, 331 ::testing::Values( 332 std::vector<std::string>({"otasigned_v1.zip", "v1"}), 333 std::vector<std::string>({"otasigned_v2.zip", "v2"}), 334 std::vector<std::string>({"otasigned_v3.zip", "v3"}), 335 std::vector<std::string>({"otasigned_v4.zip", "v4"}), 336 std::vector<std::string>({"otasigned_v5.zip", "v5"}))); 337 338 INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest, 339 ::testing::Values( 340 std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}), 341 std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}), 342 std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}), 343 std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}), 344 std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"}))); 345 346 INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest, 347 ::testing::Values( 348 std::vector<std::string>({"otasigned_v1.zip", "v2"}), 349 std::vector<std::string>({"otasigned_v2.zip", "v1"}), 350 std::vector<std::string>({"otasigned_v3.zip", "v5"}), 351 std::vector<std::string>({"otasigned_v4.zip", "v5"}), 352 std::vector<std::string>({"otasigned_v5.zip", "v3"}))); 353 354 INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest, 355 ::testing::Values( 356 std::vector<std::string>({"otasigned_v1.zip", "v3"}), 357 std::vector<std::string>({"otasigned_v2.zip", "v4"}), 358 std::vector<std::string>({"otasigned_v3.zip", "v1"}), 359 std::vector<std::string>({"otasigned_v4.zip", "v2"}))); 360 361 INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest, 362 ::testing::Values( 363 std::vector<std::string>({"random.zip", "v1"}), 364 std::vector<std::string>({"fake-eocd.zip", "v1"}))); 365