Source release 19.4.0
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "device_info_validator.h"
|
||||
#include "log.h"
|
||||
|
||||
using ::testing::AllOf;
|
||||
using ::testing::Ge;
|
||||
@@ -30,7 +31,7 @@ cppbor::Map BuildDeviceInfoMap(int version) {
|
||||
.add("model", "model")
|
||||
.add("vb_state", "green")
|
||||
.add("bootloader_state", "unlocked")
|
||||
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>()))
|
||||
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>(32, 0xCC)))
|
||||
.add("os_version", "os_version")
|
||||
.add("system_patch_level", 202312)
|
||||
.add("boot_patch_level", 20231201)
|
||||
@@ -61,6 +62,14 @@ std::vector<uint8_t> BuildDeviceInfo(int version) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
static void DumpValidatorOutput(const DeviceInfoValidator& validator) {
|
||||
const std::string out = validator.GetFormattedMessage();
|
||||
LOGI("%s", out.c_str());
|
||||
for (auto& msg : validator.GetValidateMessages()) {
|
||||
LOGE("Error code %d: %s", msg.first, msg.second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoParseError) {
|
||||
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion3);
|
||||
const std::vector<uint8_t> device_info_bad(device_info.begin(),
|
||||
@@ -87,6 +96,9 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoNotMap) {
|
||||
EXPECT_EQ(1u, msgs.size());
|
||||
EXPECT_EQ(kCborValidateFatal, msgs[0].first);
|
||||
EXPECT_THAT(msgs[0].second, HasSubstr("Device info is not a CBOR map"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest,
|
||||
@@ -95,8 +107,7 @@ TEST(OEMCryptoDeviceInfoValidatorTest,
|
||||
cppbor::Map()
|
||||
.add("brand", "brand")
|
||||
.add("manufacturer", "manufacturer")
|
||||
.add(123, 456) // Non-Tstr key type
|
||||
.add("system_patch_level", "not a uint") // Non-uint value type
|
||||
.add(123, 456) // Non-Tstr key type
|
||||
.canonicalize()
|
||||
.encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion3);
|
||||
@@ -112,25 +123,22 @@ TEST(OEMCryptoDeviceInfoValidatorTest,
|
||||
return p.second.find("Unexpected entry key type") != std::string::npos;
|
||||
});
|
||||
EXPECT_EQ(true, unexpected_key_type_found);
|
||||
const bool unexpected_value_type_found = std::any_of(
|
||||
msgs.begin(), msgs.end(),
|
||||
[](const std::pair<CborMessageStatus, std::string>& p) {
|
||||
return p.second.find("system_patch_level has the wrong type") !=
|
||||
std::string::npos;
|
||||
});
|
||||
EXPECT_EQ(true, unexpected_value_type_found);
|
||||
const bool missing_model_found = std::any_of(
|
||||
msgs.begin(), msgs.end(),
|
||||
[](const std::pair<CborMessageStatus, std::string>& p) {
|
||||
return p.second.find("model is missing") != std::string::npos;
|
||||
});
|
||||
const bool missing_model_found =
|
||||
std::any_of(msgs.begin(), msgs.end(),
|
||||
[](const std::pair<CborMessageStatus, std::string>& p) {
|
||||
return p.second.find("missing important field model") !=
|
||||
std::string::npos;
|
||||
});
|
||||
EXPECT_EQ(true, missing_model_found);
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3NonCanonical) {
|
||||
const cppbor::Map map = BuildDeviceInfoMap(kDeviceVersion3);
|
||||
const std::vector<uint8_t> device_info = map.encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion3);
|
||||
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
@@ -141,43 +149,97 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3NonCanonical) {
|
||||
EXPECT_EQ(kCborValidateError, msgs[0].first);
|
||||
EXPECT_THAT(msgs[0].second,
|
||||
HasSubstr("Device info ordering is non-canonical"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3) {
|
||||
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion3);
|
||||
DeviceInfoValidator validator(kDeviceVersion3);
|
||||
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
|
||||
const std::string out = validator.GetFormattedMessage();
|
||||
EXPECT_THAT(out, HasSubstr("manufacturer: manufacturer"));
|
||||
EXPECT_THAT(out, HasSubstr("model: model"));
|
||||
EXPECT_THAT(out, HasSubstr("fused: 0"));
|
||||
EXPECT_THAT(out, HasSubstr("manufacturer:manufacturer"));
|
||||
EXPECT_THAT(out, HasSubstr("model:model"));
|
||||
EXPECT_THAT(out, HasSubstr("fused:0"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3InvalidFields) {
|
||||
cppbor::Map device_info_map =
|
||||
cppbor::Map()
|
||||
.add("brand", "brand")
|
||||
.add("manufacturer", "manufacturer")
|
||||
.add("product", "product")
|
||||
.add("model", "model")
|
||||
.add("vb_state", "invalid_green") // invalid value
|
||||
.add("bootloader_state", "invalid_unlocked") // invalid value
|
||||
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>(32, 0xCC)))
|
||||
.add("os_version", "os_version")
|
||||
.add("system_patch_level", 100) // invalid value, expects "YYYYMM"
|
||||
.add("boot_patch_level",
|
||||
12345678) // invalid value, expectes "YYYYMMDD"
|
||||
.add("vendor_patch_level",
|
||||
"20231201") // invalid value, expects YYYYMMDD in int
|
||||
.add("security_level", "tee")
|
||||
.add("device", "device")
|
||||
.add("fused", 9); // invalid value, expects 0 or 1
|
||||
auto device_info = device_info_map.canonicalize().encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
EXPECT_THAT(result, Ge(kCborValidateError));
|
||||
const std::vector<std::pair<CborMessageStatus, std::string>> msgs =
|
||||
validator.GetValidateMessages();
|
||||
std::string out = "";
|
||||
for (auto& msg : msgs) {
|
||||
out += (msg.second + "\n");
|
||||
}
|
||||
EXPECT_THAT(out, HasSubstr("invalid value for system_patch_level"));
|
||||
EXPECT_THAT(out, HasSubstr("invalid value for boot_patch_level"));
|
||||
EXPECT_THAT(out, HasSubstr("missing required field vendor_patch_level"));
|
||||
EXPECT_THAT(out, HasSubstr("unexpected value for vb_state"));
|
||||
EXPECT_THAT(out, HasSubstr("unexpected value for bootloader_state"));
|
||||
EXPECT_THAT(out, HasSubstr("unexpected value for fused"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV2) {
|
||||
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion2);
|
||||
DeviceInfoValidator validator(kDeviceVersion2);
|
||||
DeviceInfoValidator validator(kDeviceVersion2, true /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
|
||||
const std::string out = validator.GetFormattedMessage();
|
||||
EXPECT_THAT(out, HasSubstr("manufacturer: manufacturer"));
|
||||
EXPECT_THAT(out, HasSubstr("model: model"));
|
||||
EXPECT_THAT(out, HasSubstr("fused: 0"));
|
||||
EXPECT_THAT(out, HasSubstr("version: 2"));
|
||||
EXPECT_THAT(out, HasSubstr("manufacturer:manufacturer"));
|
||||
EXPECT_THAT(out, HasSubstr("model:model"));
|
||||
EXPECT_THAT(out, HasSubstr("fused:0"));
|
||||
EXPECT_THAT(out, HasSubstr("version:2"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1MissingField) {
|
||||
const std::vector<uint8_t> device_info = cppbor::Map()
|
||||
.add("brand", "brand")
|
||||
.add("security_level", "tee")
|
||||
.add("version", 1)
|
||||
.canonicalize()
|
||||
.encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion1);
|
||||
const std::vector<uint8_t> device_info =
|
||||
cppbor::Map()
|
||||
.add("manufacturer", "manufacturer")
|
||||
.add("model", "model")
|
||||
.add("brand", "brand")
|
||||
.add("security_level", "tee")
|
||||
.add("version", 1)
|
||||
.canonicalize()
|
||||
.encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion1, true /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
@@ -186,19 +248,50 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1MissingField) {
|
||||
validator.GetValidateMessages();
|
||||
EXPECT_EQ(1u, msgs.size());
|
||||
EXPECT_EQ(kCborValidateError, msgs[0].first);
|
||||
EXPECT_THAT(msgs[0].second, HasSubstr("att_id_state is missing"));
|
||||
EXPECT_THAT(msgs[0].second, HasSubstr("missing required field att_id_state"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1) {
|
||||
DeviceInfoValidator validator(kDeviceVersion1);
|
||||
DeviceInfoValidator validator(kDeviceVersion1, true /* is_gms */);
|
||||
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion1);
|
||||
CborMessageStatus result = validator.Parse(device_info);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
|
||||
const std::string out = validator.GetFormattedMessage();
|
||||
EXPECT_THAT(out, HasSubstr("board: board"));
|
||||
EXPECT_THAT(out, HasSubstr("version: 1"));
|
||||
EXPECT_THAT(out, HasSubstr("board:board"));
|
||||
EXPECT_THAT(out, HasSubstr("version:1"));
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoMissingFused) {
|
||||
const std::vector<uint8_t> device_info_bad =
|
||||
cppbor::Map()
|
||||
.add("model", "model")
|
||||
.add("manufacturer", "manufacturer")
|
||||
.canonicalize()
|
||||
.encode();
|
||||
DeviceInfoValidator validator(kDeviceVersion1, false /* is_gms */);
|
||||
CborMessageStatus result = validator.Parse(device_info_bad);
|
||||
EXPECT_EQ(kCborParseOk, result);
|
||||
result = validator.Validate();
|
||||
EXPECT_EQ(kCborValidateWarning, result);
|
||||
const std::vector<std::pair<CborMessageStatus, std::string>> msgs =
|
||||
validator.GetValidateMessages();
|
||||
const bool missing_fused_found = std::any_of(
|
||||
msgs.begin(), msgs.end(),
|
||||
[](const std::pair<CborMessageStatus, std::string>& p) {
|
||||
return p.second.find("missing field fused") != std::string::npos;
|
||||
});
|
||||
EXPECT_EQ(true, missing_fused_found);
|
||||
if (result >= kCborValidateWarning) {
|
||||
DumpValidatorOutput(validator);
|
||||
}
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace wvoec
|
||||
|
||||
Reference in New Issue
Block a user