|
|
|
|
@@ -245,8 +245,8 @@ CborMessageStatus ConfigurationDescriptor::Validate(
|
|
|
|
|
bool* is_widevine_entry) const {
|
|
|
|
|
CborMessageStatus status = kCborParseOk;
|
|
|
|
|
const std::string component = "ConfigurationDescriptor";
|
|
|
|
|
CborMessageStatus cur_status =
|
|
|
|
|
ValidateRequiredField("component_name", component, component_name, msgs);
|
|
|
|
|
CborMessageStatus cur_status = ValidateRequiredField(
|
|
|
|
|
"component_name", component, component_name, msgs, kCborValidateWarning);
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
if (cur_status == kCborValidateOk) {
|
|
|
|
|
std::string name = component_name.second;
|
|
|
|
|
@@ -299,14 +299,14 @@ CborMessageStatus BccEntryPayload::Validate(
|
|
|
|
|
if (!is_degenerated) {
|
|
|
|
|
cur_status = ValidateRequiredField("code_hash", component, code_hash, msgs);
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
cur_status =
|
|
|
|
|
ValidateRequiredField("config_hash", component, config_hash, msgs);
|
|
|
|
|
cur_status = ValidateRequiredField("config_hash", component, config_hash,
|
|
|
|
|
msgs, kCborValidateWarning);
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
if (config_descriptor.first == kAbsent) {
|
|
|
|
|
msgs.push_back(std::make_pair(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
component + ": missing required field config_descriptor"));
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
} else {
|
|
|
|
|
cur_status = config_descriptor.second.Validate(msgs, is_widevine_entry);
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
@@ -393,9 +393,11 @@ CborMessageStatus Bcc::Validate(
|
|
|
|
|
if (is_widevine_entry) found_widevine_entry = true;
|
|
|
|
|
}
|
|
|
|
|
if (!is_degenerated && !found_widevine_entry) {
|
|
|
|
|
msgs.push_back(std::make_pair(kCborValidateError,
|
|
|
|
|
component + ": Widevine cert not found."));
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
msgs.push_back(
|
|
|
|
|
std::make_pair(kCborValidateWarning,
|
|
|
|
|
component + ": Widevine cert not found. Expect a BCC "
|
|
|
|
|
"entry with component_name: widevine"));
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
}
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
@@ -538,39 +540,45 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
for (size_t i = 1; i < bcc_array->size(); ++i) {
|
|
|
|
|
const cppbor::Array* bcc_entry = (*bcc_array)[i]->asArray();
|
|
|
|
|
if (bcc_entry == nullptr) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"BCC entry is empty at index " + std::to_string(i));
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry is empty at index " + std::to_string(i) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (bcc_entry->size() != 4) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" should contain 4 items. Actual: " +
|
|
|
|
|
std::to_string(bcc_entry->size()));
|
|
|
|
|
std::to_string(bcc_entry->size()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((*bcc_entry)[0]->type() != cppbor::BSTR) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" protected field is not a CBOR bstr.");
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" protected field is not a CBOR bstr. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((*bcc_entry)[1]->type() != cppbor::MAP) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unprotected field is not a CBOR map.");
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unprotected field is not a CBOR map. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((*bcc_entry)[2]->type() != cppbor::BSTR) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" payload field is not a CBOR bstr.");
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" payload field is not a CBOR bstr. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((*bcc_entry)[3]->type() != cppbor::BSTR) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" signature field is not a CBOR bstr.");
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" signature field is not a CBOR bstr. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -578,9 +586,9 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
const std::vector<uint8_t>& encoded_protected_data =
|
|
|
|
|
(*bcc_entry)[0]->asBstr()->value();
|
|
|
|
|
if (encoded_protected_data.empty()) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) + " empty protected data.");
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" empty protected data. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
auto parse_result = cppbor::parse(encoded_protected_data);
|
|
|
|
|
@@ -588,23 +596,25 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
std::move(std::get<0>(parse_result));
|
|
|
|
|
std::string error_message = std::move(std::get<2>(parse_result));
|
|
|
|
|
if (sub_item == nullptr || !error_message.empty()) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unable to parse protected: " + error_message);
|
|
|
|
|
" unable to parse protected: " + error_message +
|
|
|
|
|
" Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sub_item->type() != cppbor::MAP) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unexpected protected type: " +
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()));
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const cppbor::Map* protected_map = sub_item->asMap();
|
|
|
|
|
if (protected_map == nullptr) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) + " protected map is null.");
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" protected map is null. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
BccEntry entry;
|
|
|
|
|
@@ -614,9 +624,7 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
status =
|
|
|
|
|
ProcessBccEntryProtected(protected_map, &entry.protected_data.second);
|
|
|
|
|
if (status == kCborValidateFatal) return status;
|
|
|
|
|
if (status != kCborValidateError) {
|
|
|
|
|
entry.protected_data.first = kPresent;
|
|
|
|
|
}
|
|
|
|
|
entry.protected_data.first = kPresent;
|
|
|
|
|
}
|
|
|
|
|
// Unprotected data in BCC entry is always empty, which is ignored.
|
|
|
|
|
entry.unprotected.first = kEmpty;
|
|
|
|
|
@@ -645,9 +653,9 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
|
|
|
|
|
// Parse and verify the payload
|
|
|
|
|
if (encoded_payload.empty()) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) + " empty payload.");
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" empty payload. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
parse_result = cppbor::parse(encoded_payload);
|
|
|
|
|
@@ -655,24 +663,26 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
std::move(std::get<0>(parse_result));
|
|
|
|
|
error_message = std::move(std::get<2>(parse_result));
|
|
|
|
|
if (sub_item_payload == nullptr || !error_message.empty()) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unable to parse payload: " + error_message);
|
|
|
|
|
" unable to parse payload: " + error_message +
|
|
|
|
|
" Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sub_item_payload->type() != cppbor::MAP) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" unexpected payload type: " +
|
|
|
|
|
CppborMajorTypeToString(sub_item_payload->type()));
|
|
|
|
|
CppborMajorTypeToString(sub_item_payload->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const cppbor::Map* payload_map = sub_item_payload->asMap();
|
|
|
|
|
if (payload_map == nullptr) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"BCC entry index " + std::to_string(i) + " payload is empty.");
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"BCC entry index " + std::to_string(i) +
|
|
|
|
|
" payload is empty. Skip current item.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (payload_map->size() == 0) {
|
|
|
|
|
@@ -680,10 +690,8 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
} else {
|
|
|
|
|
status = ProcessDiceChainEntryPayload(payload_map, &entry.payload.second);
|
|
|
|
|
if (status == kCborValidateFatal) return status;
|
|
|
|
|
if (status != kCborValidateError) {
|
|
|
|
|
entry.payload.first = kPresent;
|
|
|
|
|
leaf_pub_key = entry.payload.second.subject_public_key.second;
|
|
|
|
|
}
|
|
|
|
|
entry.payload.first = kPresent;
|
|
|
|
|
leaf_pub_key = entry.payload.second.subject_public_key.second;
|
|
|
|
|
}
|
|
|
|
|
bcc.entries.push_back(std::move(entry));
|
|
|
|
|
}
|
|
|
|
|
@@ -704,6 +712,7 @@ CborMessageStatus BccValidator::Validate() {
|
|
|
|
|
|
|
|
|
|
CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
const cppbor::Map* config_descriptor_map, ConfigurationDescriptor* cd) {
|
|
|
|
|
CborMessageStatus status = kCborValidateOk;
|
|
|
|
|
for (size_t index = 0; index < config_descriptor_map->size(); ++index) {
|
|
|
|
|
std::pair<const std::unique_ptr<cppbor::Item>&,
|
|
|
|
|
const std::unique_ptr<cppbor::Item>&>
|
|
|
|
|
@@ -711,9 +720,11 @@ CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
if (entry.first->type() != cppbor::NINT &&
|
|
|
|
|
entry.first->type() != cppbor::UINT) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Invalid key type in configuration descriptor map: " +
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const int64_t map_key = entry.first->asInt()->value();
|
|
|
|
|
@@ -721,10 +732,12 @@ CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
case kComponentNameLabel: {
|
|
|
|
|
if (entry.second->type() != cppbor::TSTR) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Invalid value type in configuration descriptor map for "
|
|
|
|
|
"key component name: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
cd->component_name.second = entry.second->asTstr()->value();
|
|
|
|
|
@@ -742,10 +755,12 @@ CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
cd->component_version.first = kPresent;
|
|
|
|
|
} else {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Invalid value type in configuration descriptor map for "
|
|
|
|
|
"component version: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
@@ -759,7 +774,9 @@ CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Invalid value type in configuration descriptor map for "
|
|
|
|
|
"security version: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
cd->security_version.second = entry.second->asUint()->value();
|
|
|
|
|
@@ -772,11 +789,12 @@ CborMessageStatus BccValidator::ProcessConfigurationDescriptor(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return message_status_;
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
const cppbor::Map* public_key_map, BccPublicKeyInfo* public_key) {
|
|
|
|
|
CborMessageStatus status = kCborValidateOk;
|
|
|
|
|
std::vector<uint8_t> device_key_bytes_0;
|
|
|
|
|
std::vector<uint8_t> device_key_bytes_1;
|
|
|
|
|
for (size_t index = 0; index < public_key_map->size(); ++index) {
|
|
|
|
|
@@ -787,7 +805,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
entry.first->type() != cppbor::UINT) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Invalid key type in public key info map: " +
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const int64_t map_key = entry.first->asInt()->value();
|
|
|
|
|
@@ -798,7 +818,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Invalid value type in public key info map for "
|
|
|
|
|
"key MAP_KEY_DEVICE_KEY_TYPE: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
public_key->key_type.first = kPresent;
|
|
|
|
|
@@ -812,7 +834,10 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Invalid value in public key info map for key "
|
|
|
|
|
"MAP_KEY_DEVICE_KEY_TYPE: " +
|
|
|
|
|
std::to_string(value));
|
|
|
|
|
std::to_string(value) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case MAP_KEY_DEVICE_KEY_ALGORITHM: {
|
|
|
|
|
@@ -821,7 +846,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Invalid value type in public key info map for "
|
|
|
|
|
"key MAP_KEY_DEVICE_KEY_ALGORITHM: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
public_key->signature_algorithm.first = kPresent;
|
|
|
|
|
@@ -837,7 +864,10 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Invalid value in public key info map for key "
|
|
|
|
|
"MAP_KEY_DEVICE_KEY_ALGORITHM: " +
|
|
|
|
|
std::to_string(value));
|
|
|
|
|
std::to_string(value) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case MAP_KEY_DEVICE_KEY_OPS:
|
|
|
|
|
@@ -849,7 +879,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Invalid value type in public key info map for "
|
|
|
|
|
"key MAP_KEY_DEVICE_KEY_CURVE: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
public_key->curve.first = kPresent;
|
|
|
|
|
@@ -865,7 +897,10 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Invalid value in public key info map for key "
|
|
|
|
|
"MAP_KEY_DEVICE_KEY_CURVE: " +
|
|
|
|
|
std::to_string(value));
|
|
|
|
|
std::to_string(value) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case MAP_KEY_DEVICE_KEY_BYTES_0:
|
|
|
|
|
@@ -877,7 +912,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Invalid value type in public key info map for "
|
|
|
|
|
"key MAP_KEY_DEVICE_KEY_BYTES_0/1: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const std::vector<uint8_t>& key_bytes = entry.second->asBstr()->value();
|
|
|
|
|
@@ -887,7 +924,9 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
key_bytes.size() != kP384KeyComponentSize) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Malformed public key data size of: " +
|
|
|
|
|
std::to_string(key_bytes.size()));
|
|
|
|
|
std::to_string(key_bytes.size()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
public_key->key_bytes.first = kPresent;
|
|
|
|
|
@@ -904,7 +943,8 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Malformed public key definition. Missing device public key bytes.");
|
|
|
|
|
return message_status_;
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
std::vector<uint8_t> device_key_bytes;
|
|
|
|
|
if (public_key->key_type.second == DEVICE_KEY_OCTET_PAIR) {
|
|
|
|
|
@@ -921,7 +961,8 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Invalid ECDSA public key size: " +
|
|
|
|
|
std::to_string(device_key_bytes.size()));
|
|
|
|
|
return message_status_;
|
|
|
|
|
ApplyStatus(status, kCborValidateError);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
device_key_bytes = std::move(device_key_bytes_0);
|
|
|
|
|
@@ -930,11 +971,12 @@ CborMessageStatus BccValidator::ProcessSubjectPublicKeyInfo(
|
|
|
|
|
if (public_key->key_bytes.second.empty()) {
|
|
|
|
|
public_key->key_bytes.first = kEmpty;
|
|
|
|
|
}
|
|
|
|
|
return message_status_;
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CborMessageStatus BccValidator::ProcessBccEntryProtected(
|
|
|
|
|
const cppbor::Map* protected_map, BccEntryProtected* protected_data) {
|
|
|
|
|
CborMessageStatus status = kCborValidateOk;
|
|
|
|
|
for (size_t index = 0; index < protected_map->size(); ++index) {
|
|
|
|
|
std::pair<const std::unique_ptr<cppbor::Item>&,
|
|
|
|
|
const std::unique_ptr<cppbor::Item>&>
|
|
|
|
|
@@ -942,9 +984,11 @@ CborMessageStatus BccValidator::ProcessBccEntryProtected(
|
|
|
|
|
if (entry.first->type() != cppbor::NINT &&
|
|
|
|
|
entry.first->type() != cppbor::UINT) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Invalid key type in protected data map in bcc entry: " +
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.first->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const int64_t map_key = entry.first->asInt()->value();
|
|
|
|
|
@@ -953,10 +997,12 @@ CborMessageStatus BccValidator::ProcessBccEntryProtected(
|
|
|
|
|
if (entry.second->type() != cppbor::NINT &&
|
|
|
|
|
entry.second->type() != cppbor::UINT) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Invalid value type in protected data map for "
|
|
|
|
|
"key 1: " +
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()));
|
|
|
|
|
CppborMajorTypeToString(entry.second->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
protected_data->algorithm.first = kPresent;
|
|
|
|
|
@@ -964,11 +1010,12 @@ CborMessageStatus BccValidator::ProcessBccEntryProtected(
|
|
|
|
|
} break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return message_status_;
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
const cppbor::Map* payload_map, BccEntryPayload* payload) {
|
|
|
|
|
CborMessageStatus status = kCborValidateOk;
|
|
|
|
|
for (size_t i = 0; i < payload_map->size(); ++i) {
|
|
|
|
|
const auto& entry = (*payload_map)[i];
|
|
|
|
|
if (entry.first == nullptr || entry.first->asInt() == nullptr ||
|
|
|
|
|
@@ -991,7 +1038,9 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
} else if (key == kSubjectPublicKeyLabel) {
|
|
|
|
|
const auto& value = entry.second->asBstr()->value();
|
|
|
|
|
if (value.empty()) {
|
|
|
|
|
AddValidationMessage(kCborValidateError, "Empty public key.");
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"Empty public key. Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
auto parse_result = cppbor::parse(value);
|
|
|
|
|
@@ -999,14 +1048,18 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
std::move(std::get<0>(parse_result));
|
|
|
|
|
std::string error_message = std::move(std::get<2>(parse_result));
|
|
|
|
|
if (sub_item == nullptr || !error_message.empty()) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Unable to parse public key: " + error_message);
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"Unable to parse public key: " + error_message +
|
|
|
|
|
" Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sub_item->type() != cppbor::MAP || sub_item->asMap() == nullptr) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"Unexpected public key type: " +
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()));
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const cppbor::Map* public_key_map = sub_item->asMap();
|
|
|
|
|
@@ -1014,9 +1067,10 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
payload->subject_public_key.first = kEmpty;
|
|
|
|
|
} else {
|
|
|
|
|
payload->subject_public_key.first = kPresent;
|
|
|
|
|
CborMessageStatus status = ProcessSubjectPublicKeyInfo(
|
|
|
|
|
CborMessageStatus cur_status = ProcessSubjectPublicKeyInfo(
|
|
|
|
|
public_key_map, &(payload->subject_public_key.second));
|
|
|
|
|
if (status == kCborValidateFatal) return status;
|
|
|
|
|
if (cur_status == kCborValidateFatal) return cur_status;
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
}
|
|
|
|
|
} else if (key == kKeyUsageLabel) {
|
|
|
|
|
payload->key_usage.second = entry.second->asBstr()->value();
|
|
|
|
|
@@ -1037,8 +1091,10 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
} else if (key == kConfigurationDescriptorLabel) {
|
|
|
|
|
const auto& encoded_cd = entry.second->asBstr()->value();
|
|
|
|
|
if (encoded_cd.empty()) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
"Empty configuration descriptor.");
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateWarning,
|
|
|
|
|
"Empty configuration descriptor. Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
auto parse_result = cppbor::parse(encoded_cd);
|
|
|
|
|
@@ -1046,15 +1102,18 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
std::move(std::get<0>(parse_result));
|
|
|
|
|
std::string error_message = std::move(std::get<2>(parse_result));
|
|
|
|
|
if (sub_item == nullptr || !error_message.empty()) {
|
|
|
|
|
AddValidationMessage(
|
|
|
|
|
kCborValidateError,
|
|
|
|
|
"Unable to parse configuration descriptor: " + error_message);
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"Unable to parse configuration descriptor: " +
|
|
|
|
|
error_message + " Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sub_item->type() != cppbor::MAP) {
|
|
|
|
|
AddValidationMessage(kCborValidateError,
|
|
|
|
|
AddValidationMessage(kCborValidateWarning,
|
|
|
|
|
"Unexpected configuration descriptor type: " +
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()));
|
|
|
|
|
CppborMajorTypeToString(sub_item->type()) +
|
|
|
|
|
". Skip current item.");
|
|
|
|
|
ApplyStatus(status, kCborValidateWarning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const cppbor::Map* config_descriptor_map = sub_item->asMap();
|
|
|
|
|
@@ -1063,12 +1122,11 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
// OK, configuration descriptor is optional.
|
|
|
|
|
payload->config_descriptor.first = kEmpty;
|
|
|
|
|
} else {
|
|
|
|
|
CborMessageStatus status = ProcessConfigurationDescriptor(
|
|
|
|
|
CborMessageStatus cur_status = ProcessConfigurationDescriptor(
|
|
|
|
|
config_descriptor_map, &(payload->config_descriptor.second));
|
|
|
|
|
if (status == kCborValidateFatal) return status;
|
|
|
|
|
if (status != kCborValidateError) {
|
|
|
|
|
payload->config_descriptor.first = kPresent;
|
|
|
|
|
}
|
|
|
|
|
if (cur_status == kCborValidateFatal) return cur_status;
|
|
|
|
|
ApplyStatus(status, cur_status);
|
|
|
|
|
payload->config_descriptor.first = kPresent;
|
|
|
|
|
}
|
|
|
|
|
} else if (key == kAuthorityHashLabel) {
|
|
|
|
|
payload->authority_hash.second = entry.second->asBstr()->value();
|
|
|
|
|
@@ -1083,7 +1141,7 @@ CborMessageStatus BccValidator::ProcessDiceChainEntryPayload(
|
|
|
|
|
payload->mode.first = payload->mode.second.empty() ? kEmpty : kPresent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return message_status_;
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string BccValidator::GetFormattedMessage() const {
|
|
|
|
|
|