summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk10
-rw-r--r--tests/component/edify_test.cpp5
-rw-r--r--tests/component/imgdiff_test.cpp9
-rw-r--r--tests/component/updater_test.cpp172
-rw-r--r--tests/component/verifier_test.cpp206
-rw-r--r--tests/unit/asn1_decoder_test.cpp397
6 files changed, 464 insertions, 335 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index ec971b38c..ff6e14c9b 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -81,7 +81,10 @@ include $(BUILD_NATIVE_TEST)
# Component tests
include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Werror
+LOCAL_CFLAGS := \
+ -Werror \
+ -D_FILE_OFFSET_BITS=64
+
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE := recovery_component_test
LOCAL_C_INCLUDES := bootable/recovery
@@ -117,7 +120,6 @@ LOCAL_STATIC_LIBRARIES := \
libupdater \
libbootloader_message \
libverifier \
- libminui \
libotautil \
libmounts \
libdivsufsort \
@@ -136,6 +138,10 @@ LOCAL_STATIC_LIBRARIES := \
libz \
libbase \
libtune2fs \
+ libfec \
+ libfec_rs \
+ libsquashfs_utils \
+ libcutils \
$(tune2fs_static_libraries)
testdata_files := $(call find-subdir-files, testdata/*)
diff --git a/tests/component/edify_test.cpp b/tests/component/edify_test.cpp
index 287e40cc6..61a1e6b64 100644
--- a/tests/component/edify_test.cpp
+++ b/tests/component/edify_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <memory>
#include <string>
#include <gtest/gtest.h>
@@ -21,7 +22,7 @@
#include "edify/expr.h"
static void expect(const char* expr_str, const char* expected) {
- Expr* e;
+ std::unique_ptr<Expr> e;
int error_count = 0;
EXPECT_EQ(0, parse_string(expr_str, &e, &error_count));
EXPECT_EQ(0, error_count);
@@ -152,7 +153,7 @@ TEST_F(EdifyTest, big_string) {
TEST_F(EdifyTest, unknown_function) {
// unknown function
const char* script1 = "unknown_function()";
- Expr* expr;
+ std::unique_ptr<Expr> expr;
int error_count = 0;
EXPECT_EQ(1, parse_string(script1, &expr, &error_count));
EXPECT_EQ(1, error_count);
diff --git a/tests/component/imgdiff_test.cpp b/tests/component/imgdiff_test.cpp
index be2dd385b..2f648501c 100644
--- a/tests/component/imgdiff_test.cpp
+++ b/tests/component/imgdiff_test.cpp
@@ -18,13 +18,14 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/memory.h>
#include <android-base/test_utils.h>
#include <applypatch/imgdiff.h>
#include <applypatch/imgpatch.h>
#include <gtest/gtest.h>
#include <ziparchive/zip_writer.h>
-#include "applypatch/utils.h"
+using android::base::get_unaligned;
static ssize_t MemorySink(const unsigned char* data, ssize_t len, void* token) {
std::string* s = static_cast<std::string*>(token);
@@ -41,7 +42,7 @@ static void verify_patch_header(const std::string& patch, size_t* num_normal, si
ASSERT_GE(size, 12U);
ASSERT_EQ("IMGDIFF2", std::string(data, 8));
- const int num_chunks = Read4(data + 8);
+ const int num_chunks = get_unaligned<int32_t>(data + 8);
ASSERT_GE(num_chunks, 0);
size_t normal = 0;
@@ -51,7 +52,7 @@ static void verify_patch_header(const std::string& patch, size_t* num_normal, si
size_t pos = 12;
for (int i = 0; i < num_chunks; ++i) {
ASSERT_LE(pos + 4, size);
- int type = Read4(data + pos);
+ int type = get_unaligned<int32_t>(data + pos);
pos += 4;
if (type == CHUNK_NORMAL) {
pos += 24;
@@ -59,7 +60,7 @@ static void verify_patch_header(const std::string& patch, size_t* num_normal, si
normal++;
} else if (type == CHUNK_RAW) {
ASSERT_LE(pos + 4, size);
- ssize_t data_len = Read4(data + pos);
+ ssize_t data_len = get_unaligned<int32_t>(data + pos);
ASSERT_GT(data_len, 0);
pos += 4 + data_len;
ASSERT_LE(pos, size);
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
index 8c4bdbaa4..5652ddf46 100644
--- a/tests/component/updater_test.cpp
+++ b/tests/component/updater_test.cpp
@@ -19,7 +19,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include <memory>
#include <string>
+#include <vector>
#include <android-base/file.h>
#include <android-base/properties.h>
@@ -27,12 +29,17 @@
#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <bootloader_message/bootloader_message.h>
+#include <bsdiff.h>
#include <gtest/gtest.h>
#include <ziparchive/zip_archive.h>
+#include <ziparchive/zip_writer.h>
#include "common/test_constants.h"
#include "edify/expr.h"
#include "error_code.h"
+#include "otautil/SysUtil.h"
+#include "print_sha1.h"
+#include "updater/blockimg.h"
#include "updater/install.h"
#include "updater/updater.h"
@@ -40,7 +47,7 @@ struct selabel_handle *sehandle = nullptr;
static void expect(const char* expected, const char* expr_str, CauseCode cause_code,
UpdaterInfo* info = nullptr) {
- Expr* e;
+ std::unique_ptr<Expr> e;
int error_count = 0;
ASSERT_EQ(0, parse_string(expr_str, &e, &error_count));
ASSERT_EQ(0, error_count);
@@ -64,12 +71,19 @@ static void expect(const char* expected, const char* expr_str, CauseCode cause_c
ASSERT_EQ(cause_code, state.cause_code);
}
+static std::string get_sha1(const std::string& content) {
+ uint8_t digest[SHA_DIGEST_LENGTH];
+ SHA1(reinterpret_cast<const uint8_t*>(content.c_str()), content.size(), digest);
+ return print_sha1(digest);
+}
+
class UpdaterTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- RegisterBuiltins();
- RegisterInstallFunctions();
- }
+ protected:
+ virtual void SetUp() override {
+ RegisterBuiltins();
+ RegisterInstallFunctions();
+ RegisterBlockImageFunctions();
+ }
};
TEST_F(UpdaterTest, getprop) {
@@ -113,6 +127,55 @@ TEST_F(UpdaterTest, sha1_check) {
expect(nullptr, "sha1_check()", kArgsParsingFailure);
}
+TEST_F(UpdaterTest, apply_patch_check) {
+ // Zero-argument is not valid.
+ expect(nullptr, "apply_patch_check()", kArgsParsingFailure);
+
+ // File not found.
+ expect("", "apply_patch_check(\"/doesntexist\")", kNoCause);
+
+ std::string src_file = from_testdata_base("old.file");
+ std::string src_content;
+ ASSERT_TRUE(android::base::ReadFileToString(src_file, &src_content));
+ size_t src_size = src_content.size();
+ std::string src_hash = get_sha1(src_content);
+
+ // One-argument with EMMC:file:size:sha1 should pass the check.
+ std::string filename = android::base::Join(
+ std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size), src_hash }, ":");
+ std::string cmd = "apply_patch_check(\"" + filename + "\")";
+ expect("t", cmd.c_str(), kNoCause);
+
+ // EMMC:file:(size-1):sha1:(size+1):sha1 should fail the check.
+ std::string filename_bad = android::base::Join(
+ std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1), src_hash,
+ std::to_string(src_size + 1), src_hash },
+ ":");
+ cmd = "apply_patch_check(\"" + filename_bad + "\")";
+ expect("", cmd.c_str(), kNoCause);
+
+ // EMMC:file:(size-1):sha1:size:sha1:(size+1):sha1 should pass the check.
+ filename_bad =
+ android::base::Join(std::vector<std::string>{ "EMMC", src_file, std::to_string(src_size - 1),
+ src_hash, std::to_string(src_size), src_hash,
+ std::to_string(src_size + 1), src_hash },
+ ":");
+ cmd = "apply_patch_check(\"" + filename_bad + "\")";
+ expect("t", cmd.c_str(), kNoCause);
+
+ // Multiple arguments.
+ cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"wrong_sha2\")";
+ expect("", cmd.c_str(), kNoCause);
+
+ cmd = "apply_patch_check(\"" + filename + "\", \"wrong_sha1\", \"" + src_hash +
+ "\", \"wrong_sha2\")";
+ expect("t", cmd.c_str(), kNoCause);
+
+ cmd = "apply_patch_check(\"" + filename_bad + "\", \"wrong_sha1\", \"" + src_hash +
+ "\", \"wrong_sha2\")";
+ expect("t", cmd.c_str(), kNoCause);
+}
+
TEST_F(UpdaterTest, file_getprop) {
// file_getprop() expects two arguments.
expect(nullptr, "file_getprop()", kArgsParsingFailure);
@@ -447,3 +510,100 @@ TEST_F(UpdaterTest, show_progress) {
// recovery-updater protocol expects 3 tokens ("progress <frac> <secs>").
ASSERT_EQ(3U, android::base::Split(cmd, " ").size());
}
+
+TEST_F(UpdaterTest, block_image_update) {
+ // Create a zip file with new_data and patch_data.
+ TemporaryFile zip_file;
+ FILE* zip_file_ptr = fdopen(zip_file.fd, "wb");
+ ZipWriter zip_writer(zip_file_ptr);
+
+ // Add a dummy new data.
+ ASSERT_EQ(0, zip_writer.StartEntry("new_data", 0));
+ ASSERT_EQ(0, zip_writer.FinishEntry());
+
+ // Generate and add the patch data.
+ std::string src_content = std::string(4096, 'a') + std::string(4096, 'c');
+ std::string tgt_content = std::string(4096, 'b') + std::string(4096, 'd');
+ TemporaryFile patch_file;
+ ASSERT_EQ(0, bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(src_content.data()),
+ src_content.size(), reinterpret_cast<const uint8_t*>(tgt_content.data()),
+ tgt_content.size(), patch_file.path, nullptr));
+ std::string patch_content;
+ ASSERT_TRUE(android::base::ReadFileToString(patch_file.path, &patch_content));
+ ASSERT_EQ(0, zip_writer.StartEntry("patch_data", 0));
+ ASSERT_EQ(0, zip_writer.WriteBytes(patch_content.data(), patch_content.size()));
+ ASSERT_EQ(0, zip_writer.FinishEntry());
+
+ // Add two transfer lists. The first one contains a bsdiff; and we expect the update to succeed.
+ std::string src_hash = get_sha1(src_content);
+ std::string tgt_hash = get_sha1(tgt_content);
+ std::vector<std::string> transfer_list = {
+ "4",
+ "2",
+ "0",
+ "2",
+ "stash " + src_hash + " 2,0,2",
+ android::base::StringPrintf("bsdiff 0 %zu %s %s 2,0,2 2 - %s:2,0,2", patch_content.size(),
+ src_hash.c_str(), tgt_hash.c_str(), src_hash.c_str()),
+ "free " + src_hash,
+ };
+ ASSERT_EQ(0, zip_writer.StartEntry("transfer_list", 0));
+ std::string commands = android::base::Join(transfer_list, '\n');
+ ASSERT_EQ(0, zip_writer.WriteBytes(commands.data(), commands.size()));
+ ASSERT_EQ(0, zip_writer.FinishEntry());
+
+ // Stash and free some blocks, then fail the 2nd update intentionally.
+ std::vector<std::string> fail_transfer_list = {
+ "4",
+ "2",
+ "0",
+ "2",
+ "stash " + tgt_hash + " 2,0,2",
+ "free " + tgt_hash,
+ "fail",
+ };
+ ASSERT_EQ(0, zip_writer.StartEntry("fail_transfer_list", 0));
+ std::string fail_commands = android::base::Join(fail_transfer_list, '\n');
+ ASSERT_EQ(0, zip_writer.WriteBytes(fail_commands.data(), fail_commands.size()));
+ ASSERT_EQ(0, zip_writer.FinishEntry());
+ ASSERT_EQ(0, zip_writer.Finish());
+ ASSERT_EQ(0, fclose(zip_file_ptr));
+
+ MemMapping map;
+ ASSERT_EQ(0, sysMapFile(zip_file.path, &map));
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle));
+
+ // Set up the handler, command_pipe, patch offset & length.
+ UpdaterInfo updater_info;
+ updater_info.package_zip = handle;
+ TemporaryFile temp_pipe;
+ updater_info.cmd_pipe = fopen(temp_pipe.path, "wb");
+ updater_info.package_zip_addr = map.addr;
+ updater_info.package_zip_len = map.length;
+
+ // Execute the commands in the 1st transfer list.
+ TemporaryFile update_file;
+ ASSERT_TRUE(android::base::WriteStringToFile(src_content, update_file.path));
+ std::string script = "block_image_update(\"" + std::string(update_file.path) +
+ R"(", package_extract_file("transfer_list"), "new_data", "patch_data"))";
+ expect("t", script.c_str(), kNoCause, &updater_info);
+ // The update_file should be patched correctly.
+ std::string updated_content;
+ ASSERT_TRUE(android::base::ReadFileToString(update_file.path, &updated_content));
+ ASSERT_EQ(tgt_hash, get_sha1(updated_content));
+
+ // Expect the 2nd update to fail, but expect the stashed blocks to be freed.
+ script = "block_image_update(\"" + std::string(update_file.path) +
+ R"(", package_extract_file("fail_transfer_list"), "new_data", "patch_data"))";
+ expect("", script.c_str(), kNoCause, &updater_info);
+ // Updater generates the stash name based on the input file name.
+ std::string name_digest = get_sha1(update_file.path);
+ std::string stash_base = "/cache/recovery/" + name_digest;
+ ASSERT_EQ(0, access(stash_base.c_str(), F_OK));
+ ASSERT_EQ(-1, access((stash_base + tgt_hash).c_str(), F_OK));
+ ASSERT_EQ(0, rmdir(stash_base.c_str()));
+
+ ASSERT_EQ(0, fclose(updater_info.cmd_pipe));
+ CloseArchive(handle);
+}
diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp
index b740af96b..07a8c960f 100644
--- a/tests/component/verifier_test.cpp
+++ b/tests/component/verifier_test.cpp
@@ -22,93 +22,34 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include <memory>
#include <string>
#include <vector>
-#include <openssl/sha.h>
-
+#include <android-base/file.h>
#include <android-base/stringprintf.h>
-#include <ziparchive/zip_archive.h>
+#include <android-base/test_utils.h>
-#include "common.h"
#include "common/test_constants.h"
#include "otautil/SysUtil.h"
-#include "ui.h"
#include "verifier.h"
-RecoveryUI* ui = NULL;
-
-class MockUI : public RecoveryUI {
- bool Init(const std::string&) override {
- return true;
- }
- void SetStage(int, int) override {}
- void SetBackground(Icon /*icon*/) override {}
- void SetSystemUpdateText(bool /*security_update*/) override {}
-
- void SetProgressType(ProgressType /*determinate*/) override {}
- void ShowProgress(float /*portion*/, float /*seconds*/) override {}
- void SetProgress(float /*fraction*/) override {}
-
- void ShowText(bool /*visible*/) override {}
- bool IsTextVisible() override {
- return false;
- }
- bool WasTextEverVisible() override {
- return false;
- }
- void Print(const char* fmt, ...) override {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- }
- void PrintOnScreenOnly(const char* fmt, ...) override {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- }
- void ShowFile(const char*) override {}
-
- void StartMenu(const char* const* /*headers*/, const char* const* /*items*/,
- int /*initial_selection*/) override {}
- int SelectMenu(int /*sel*/) override {
- return 0;
- }
- void EndMenu() override {}
-};
-
-void
-ui_print(const char* format, ...) {
- va_list ap;
- va_start(ap, format);
- vfprintf(stdout, format, ap);
- va_end(ap);
-}
-
class VerifierTest : public testing::TestWithParam<std::vector<std::string>> {
- public:
- MemMapping memmap;
- std::vector<Certificate> certs;
-
- virtual void SetUp() {
- std::vector<std::string> args = GetParam();
- std::string package = from_testdata_base(args[0]);
- if (sysMapFile(package.c_str(), &memmap) != 0) {
- FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n";
- }
-
- for (auto it = ++(args.cbegin()); it != args.cend(); ++it) {
- std::string public_key_file = from_testdata_base("testkey_" + *it + ".txt");
- ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
- }
+ protected:
+ void SetUp() override {
+ std::vector<std::string> args = GetParam();
+ std::string package = from_testdata_base(args[0]);
+ if (sysMapFile(package.c_str(), &memmap) != 0) {
+ FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n";
}
- static void SetUpTestCase() {
- ui = new MockUI();
+ for (auto it = ++args.cbegin(); it != args.cend(); ++it) {
+ std::string public_key_file = from_testdata_base("testkey_" + *it + ".txt");
+ ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
}
+ }
+
+ MemMapping memmap;
+ std::vector<Certificate> certs;
};
class VerifierSuccessTest : public VerifierTest {
@@ -117,48 +58,105 @@ class VerifierSuccessTest : public VerifierTest {
class VerifierFailureTest : public VerifierTest {
};
+TEST(VerifierTest, load_keys_multiple_keys) {
+ std::string testkey_v4;
+ ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("testkey_v4.txt"), &testkey_v4));
+
+ std::string testkey_v3;
+ ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("testkey_v3.txt"), &testkey_v3));
+
+ std::string keys = testkey_v4 + "," + testkey_v3 + "," + testkey_v4;
+ TemporaryFile key_file1;
+ ASSERT_TRUE(android::base::WriteStringToFile(keys, key_file1.path));
+ std::vector<Certificate> certs;
+ ASSERT_TRUE(load_keys(key_file1.path, certs));
+ ASSERT_EQ(3U, certs.size());
+}
+
+TEST(VerifierTest, load_keys_invalid_keys) {
+ std::vector<Certificate> certs;
+ ASSERT_FALSE(load_keys("/doesntexist", certs));
+
+ // Empty file.
+ TemporaryFile key_file1;
+ ASSERT_FALSE(load_keys(key_file1.path, certs));
+
+ // Invalid contents.
+ ASSERT_TRUE(android::base::WriteStringToFile("invalid", key_file1.path));
+ ASSERT_FALSE(load_keys(key_file1.path, certs));
+
+ std::string testkey_v4;
+ ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("testkey_v4.txt"), &testkey_v4));
+
+ // Invalid key version: "v4 ..." => "v6 ...".
+ std::string invalid_key2(testkey_v4);
+ invalid_key2[1] = '6';
+ TemporaryFile key_file2;
+ ASSERT_TRUE(android::base::WriteStringToFile(invalid_key2, key_file2.path));
+ ASSERT_FALSE(load_keys(key_file2.path, certs));
+
+ // Invalid key content: inserted extra bytes ",2209831334".
+ std::string invalid_key3(testkey_v4);
+ invalid_key3.insert(invalid_key2.size() - 2, ",2209831334");
+ TemporaryFile key_file3;
+ ASSERT_TRUE(android::base::WriteStringToFile(invalid_key3, key_file3.path));
+ ASSERT_FALSE(load_keys(key_file3.path, certs));
+
+ // Invalid key: the last key must not end with an extra ','.
+ std::string invalid_key4 = testkey_v4 + ",";
+ TemporaryFile key_file4;
+ ASSERT_TRUE(android::base::WriteStringToFile(invalid_key4, key_file4.path));
+ ASSERT_FALSE(load_keys(key_file4.path, certs));
+
+ // Invalid key separator.
+ std::string invalid_key5 = testkey_v4 + ";" + testkey_v4;
+ TemporaryFile key_file5;
+ ASSERT_TRUE(android::base::WriteStringToFile(invalid_key5, key_file5.path));
+ ASSERT_FALSE(load_keys(key_file5.path, certs));
+}
+
TEST_P(VerifierSuccessTest, VerifySucceed) {
- ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_SUCCESS);
+ ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs, nullptr), VERIFY_SUCCESS);
}
TEST_P(VerifierFailureTest, VerifyFailure) {
- ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_FAILURE);
+ ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs, nullptr), VERIFY_FAILURE);
}
INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest,
- ::testing::Values(
- std::vector<std::string>({"otasigned_v1.zip", "v1"}),
- std::vector<std::string>({"otasigned_v2.zip", "v2"}),
- std::vector<std::string>({"otasigned_v3.zip", "v3"}),
- std::vector<std::string>({"otasigned_v4.zip", "v4"}),
- std::vector<std::string>({"otasigned_v5.zip", "v5"})));
+ ::testing::Values(
+ std::vector<std::string>({"otasigned_v1.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v2"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v3"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v4"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v5"})));
INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest,
- ::testing::Values(
- std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}),
- std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}),
- std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}),
- std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}),
- std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"})));
+ ::testing::Values(
+ std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"})));
INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest,
- ::testing::Values(
- std::vector<std::string>({"otasigned_v1.zip", "v2"}),
- std::vector<std::string>({"otasigned_v2.zip", "v1"}),
- std::vector<std::string>({"otasigned_v3.zip", "v5"}),
- std::vector<std::string>({"otasigned_v4.zip", "v5"}),
- std::vector<std::string>({"otasigned_v5.zip", "v3"})));
+ ::testing::Values(
+ std::vector<std::string>({"otasigned_v1.zip", "v2"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v5"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v5"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v3"})));
INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest,
- ::testing::Values(
- std::vector<std::string>({"otasigned_v1.zip", "v3"}),
- std::vector<std::string>({"otasigned_v2.zip", "v4"}),
- std::vector<std::string>({"otasigned_v3.zip", "v1"}),
- std::vector<std::string>({"otasigned_v4.zip", "v2"})));
+ ::testing::Values(
+ std::vector<std::string>({"otasigned_v1.zip", "v3"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v4"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v2"})));
INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest,
- ::testing::Values(
- std::vector<std::string>({"random.zip", "v1"}),
- std::vector<std::string>({"fake-eocd.zip", "v1"}),
- std::vector<std::string>({"alter-metadata.zip", "v1"}),
- std::vector<std::string>({"alter-footer.zip", "v1"})));
+ ::testing::Values(
+ std::vector<std::string>({"random.zip", "v1"}),
+ std::vector<std::string>({"fake-eocd.zip", "v1"}),
+ std::vector<std::string>({"alter-metadata.zip", "v1"}),
+ std::vector<std::string>({"alter-footer.zip", "v1"})));
diff --git a/tests/unit/asn1_decoder_test.cpp b/tests/unit/asn1_decoder_test.cpp
index af96d87d2..b334a655b 100644
--- a/tests/unit/asn1_decoder_test.cpp
+++ b/tests/unit/asn1_decoder_test.cpp
@@ -14,225 +14,188 @@
* limitations under the License.
*/
-#define LOG_TAG "asn1_decoder_test"
+#include <stdint.h>
+
+#include <memory>
-#include <cutils/log.h>
#include <gtest/gtest.h>
-#include <stdint.h>
-#include <unistd.h>
#include "asn1_decoder.h"
-namespace android {
-
-class Asn1DecoderTest : public testing::Test {
-};
-
-TEST_F(Asn1DecoderTest, Empty_Failure) {
- uint8_t empty[] = { };
- asn1_context_t* ctx = asn1_context_new(empty, sizeof(empty));
-
- EXPECT_EQ(NULL, asn1_constructed_get(ctx));
- EXPECT_FALSE(asn1_constructed_skip_all(ctx));
- EXPECT_EQ(0, asn1_constructed_type(ctx));
- EXPECT_EQ(NULL, asn1_sequence_get(ctx));
- EXPECT_EQ(NULL, asn1_set_get(ctx));
- EXPECT_FALSE(asn1_sequence_next(ctx));
-
- uint8_t* junk;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ctx, &junk, &length));
- EXPECT_FALSE(asn1_octet_string_get(ctx, &junk, &length));
-
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedGet_TruncatedLength_Failure) {
- uint8_t truncated[] = { 0xA0, 0x82, };
- asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated));
- EXPECT_EQ(NULL, asn1_constructed_get(ctx));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedGet_LengthTooBig_Failure) {
- uint8_t truncated[] = { 0xA0, 0x8a, 0xA5, 0x5A, 0xA5, 0x5A,
- 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, };
- asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated));
- EXPECT_EQ(NULL, asn1_constructed_get(ctx));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedGet_TooSmallForChild_Failure) {
- uint8_t data[] = { 0xA5, 0x02, 0x06, 0x01, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_constructed_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- EXPECT_EQ(5, asn1_constructed_type(ptr));
- uint8_t* oid;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length));
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedGet_Success) {
- uint8_t data[] = { 0xA5, 0x03, 0x06, 0x01, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_constructed_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- EXPECT_EQ(5, asn1_constructed_type(ptr));
- uint8_t* oid;
- size_t length;
- ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0x01U, *oid);
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedSkipAll_TruncatedLength_Failure) {
- uint8_t truncated[] = { 0xA2, 0x82, };
- asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated));
- EXPECT_FALSE(asn1_constructed_skip_all(ctx));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, ConstructedSkipAll_Success) {
- uint8_t data[] = { 0xA0, 0x03, 0x02, 0x01, 0x01,
- 0xA1, 0x03, 0x02, 0x01, 0x01,
- 0x06, 0x01, 0xA5, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- ASSERT_TRUE(asn1_constructed_skip_all(ctx));
- uint8_t* oid;
- size_t length;
- ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0xA5U, *oid);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SequenceGet_TruncatedLength_Failure) {
- uint8_t truncated[] = { 0x30, 0x82, };
- asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated));
- EXPECT_EQ(NULL, asn1_sequence_get(ctx));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SequenceGet_TooSmallForChild_Failure) {
- uint8_t data[] = { 0x30, 0x02, 0x06, 0x01, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_sequence_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- uint8_t* oid;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length));
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SequenceGet_Success) {
- uint8_t data[] = { 0x30, 0x03, 0x06, 0x01, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_sequence_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- uint8_t* oid;
- size_t length;
- ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0x01U, *oid);
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SetGet_TruncatedLength_Failure) {
- uint8_t truncated[] = { 0x31, 0x82, };
- asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated));
- EXPECT_EQ(NULL, asn1_set_get(ctx));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SetGet_TooSmallForChild_Failure) {
- uint8_t data[] = { 0x31, 0x02, 0x06, 0x01, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_set_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- uint8_t* oid;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length));
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, SetGet_Success) {
- uint8_t data[] = { 0x31, 0x03, 0x06, 0x01, 0xBA, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- asn1_context_t* ptr = asn1_set_get(ctx);
- ASSERT_NE((asn1_context_t*)NULL, ptr);
- uint8_t* oid;
- size_t length;
- ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0xBAU, *oid);
- asn1_context_free(ptr);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OidGet_LengthZero_Failure) {
- uint8_t data[] = { 0x06, 0x00, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* oid;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OidGet_TooSmall_Failure) {
- uint8_t data[] = { 0x06, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* oid;
- size_t length;
- EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OidGet_Success) {
- uint8_t data[] = { 0x06, 0x01, 0x99, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* oid;
- size_t length;
- ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0x99U, *oid);
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) {
- uint8_t data[] = { 0x04, 0x00, 0x55, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* string;
- size_t length;
- ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) {
- uint8_t data[] = { 0x04, 0x01, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* string;
- size_t length;
- ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length));
- asn1_context_free(ctx);
-}
-
-TEST_F(Asn1DecoderTest, OctetStringGet_Success) {
- uint8_t data[] = { 0x04, 0x01, 0xAA, };
- asn1_context_t* ctx = asn1_context_new(data, sizeof(data));
- uint8_t* string;
- size_t length;
- ASSERT_TRUE(asn1_octet_string_get(ctx, &string, &length));
- EXPECT_EQ(1U, length);
- EXPECT_EQ(0xAAU, *string);
- asn1_context_free(ctx);
-}
-
-} // namespace android
+TEST(Asn1DecoderTest, Empty_Failure) {
+ uint8_t empty[] = {};
+ asn1_context ctx(empty, sizeof(empty));
+
+ ASSERT_EQ(nullptr, ctx.asn1_constructed_get());
+ ASSERT_FALSE(ctx.asn1_constructed_skip_all());
+ ASSERT_EQ(0, ctx.asn1_constructed_type());
+ ASSERT_EQ(nullptr, ctx.asn1_sequence_get());
+ ASSERT_EQ(nullptr, ctx.asn1_set_get());
+ ASSERT_FALSE(ctx.asn1_sequence_next());
+
+ const uint8_t* junk;
+ size_t length;
+ ASSERT_FALSE(ctx.asn1_oid_get(&junk, &length));
+ ASSERT_FALSE(ctx.asn1_octet_string_get(&junk, &length));
+}
+
+TEST(Asn1DecoderTest, ConstructedGet_TruncatedLength_Failure) {
+ uint8_t truncated[] = { 0xA0, 0x82 };
+ asn1_context ctx(truncated, sizeof(truncated));
+ ASSERT_EQ(nullptr, ctx.asn1_constructed_get());
+}
+
+TEST(Asn1DecoderTest, ConstructedGet_LengthTooBig_Failure) {
+ uint8_t truncated[] = { 0xA0, 0x8a, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A };
+ asn1_context ctx(truncated, sizeof(truncated));
+ ASSERT_EQ(nullptr, ctx.asn1_constructed_get());
+}
+
+TEST(Asn1DecoderTest, ConstructedGet_TooSmallForChild_Failure) {
+ uint8_t data[] = { 0xA5, 0x02, 0x06, 0x01, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_constructed_get());
+ ASSERT_NE(nullptr, ptr);
+ ASSERT_EQ(5, ptr->asn1_constructed_type());
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length));
+}
+
+TEST(Asn1DecoderTest, ConstructedGet_Success) {
+ uint8_t data[] = { 0xA5, 0x03, 0x06, 0x01, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_constructed_get());
+ ASSERT_NE(nullptr, ptr);
+ ASSERT_EQ(5, ptr->asn1_constructed_type());
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0x01U, *oid);
+}
+
+TEST(Asn1DecoderTest, ConstructedSkipAll_TruncatedLength_Failure) {
+ uint8_t truncated[] = { 0xA2, 0x82 };
+ asn1_context ctx(truncated, sizeof(truncated));
+ ASSERT_FALSE(ctx.asn1_constructed_skip_all());
+}
+
+TEST(Asn1DecoderTest, ConstructedSkipAll_Success) {
+ uint8_t data[] = { 0xA0, 0x03, 0x02, 0x01, 0x01, 0xA1, 0x03, 0x02, 0x01, 0x01, 0x06, 0x01, 0xA5 };
+ asn1_context ctx(data, sizeof(data));
+ ASSERT_TRUE(ctx.asn1_constructed_skip_all());
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_TRUE(ctx.asn1_oid_get(&oid, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0xA5U, *oid);
+}
+
+TEST(Asn1DecoderTest, SequenceGet_TruncatedLength_Failure) {
+ uint8_t truncated[] = { 0x30, 0x82 };
+ asn1_context ctx(truncated, sizeof(truncated));
+ ASSERT_EQ(nullptr, ctx.asn1_sequence_get());
+}
+
+TEST(Asn1DecoderTest, SequenceGet_TooSmallForChild_Failure) {
+ uint8_t data[] = { 0x30, 0x02, 0x06, 0x01, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_sequence_get());
+ ASSERT_NE(nullptr, ptr);
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length));
+}
+
+TEST(Asn1DecoderTest, SequenceGet_Success) {
+ uint8_t data[] = { 0x30, 0x03, 0x06, 0x01, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_sequence_get());
+ ASSERT_NE(nullptr, ptr);
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0x01U, *oid);
+}
+
+TEST(Asn1DecoderTest, SetGet_TruncatedLength_Failure) {
+ uint8_t truncated[] = { 0x31, 0x82 };
+ asn1_context ctx(truncated, sizeof(truncated));
+ ASSERT_EQ(nullptr, ctx.asn1_set_get());
+}
+
+TEST(Asn1DecoderTest, SetGet_TooSmallForChild_Failure) {
+ uint8_t data[] = { 0x31, 0x02, 0x06, 0x01, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_set_get());
+ ASSERT_NE(nullptr, ptr);
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length));
+}
+
+TEST(Asn1DecoderTest, SetGet_Success) {
+ uint8_t data[] = { 0x31, 0x03, 0x06, 0x01, 0xBA };
+ asn1_context ctx(data, sizeof(data));
+ std::unique_ptr<asn1_context> ptr(ctx.asn1_set_get());
+ ASSERT_NE(nullptr, ptr);
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0xBAU, *oid);
+}
+
+TEST(Asn1DecoderTest, OidGet_LengthZero_Failure) {
+ uint8_t data[] = { 0x06, 0x00, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_FALSE(ctx.asn1_oid_get(&oid, &length));
+}
+
+TEST(Asn1DecoderTest, OidGet_TooSmall_Failure) {
+ uint8_t data[] = { 0x06, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_FALSE(ctx.asn1_oid_get(&oid, &length));
+}
+
+TEST(Asn1DecoderTest, OidGet_Success) {
+ uint8_t data[] = { 0x06, 0x01, 0x99 };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* oid;
+ size_t length;
+ ASSERT_TRUE(ctx.asn1_oid_get(&oid, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0x99U, *oid);
+}
+
+TEST(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) {
+ uint8_t data[] = { 0x04, 0x00, 0x55 };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* string;
+ size_t length;
+ ASSERT_FALSE(ctx.asn1_octet_string_get(&string, &length));
+}
+
+TEST(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) {
+ uint8_t data[] = { 0x04, 0x01 };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* string;
+ size_t length;
+ ASSERT_FALSE(ctx.asn1_octet_string_get(&string, &length));
+}
+
+TEST(Asn1DecoderTest, OctetStringGet_Success) {
+ uint8_t data[] = { 0x04, 0x01, 0xAA };
+ asn1_context ctx(data, sizeof(data));
+ const uint8_t* string;
+ size_t length;
+ ASSERT_TRUE(ctx.asn1_octet_string_get(&string, &length));
+ ASSERT_EQ(1U, length);
+ ASSERT_EQ(0xAAU, *string);
+}