Validator that can parse and validate device info Cbor object. This is to support better prov40 unit tests regarding OEMCrypto_GetDeviceInformation() later. Test: opk_ta_p40 Bug: 300304834 Change-Id: Ic260a6626dffcbef5d6b386263839499f83a69db
141 lines
3.9 KiB
C++
141 lines
3.9 KiB
C++
// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
//
|
|
// Reference implementation utilities of OEMCrypto APIs
|
|
//
|
|
#include "cbor_validator.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <cstdint>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace wvoec {
|
|
namespace util {
|
|
std::string CppborMajorTypeToString(cppbor::MajorType type) {
|
|
switch (type) {
|
|
case cppbor::UINT:
|
|
return "UINT";
|
|
case cppbor::NINT:
|
|
return "NINT";
|
|
case cppbor::BSTR:
|
|
return "BSTR";
|
|
case cppbor::TSTR:
|
|
return "TSTR";
|
|
case cppbor::ARRAY:
|
|
return "ARRAY";
|
|
case cppbor::MAP:
|
|
return "MAP";
|
|
case cppbor::SEMANTIC:
|
|
return "SEMANTIC";
|
|
case cppbor::SIMPLE:
|
|
return "SIMPLE";
|
|
}
|
|
return "undefined type";
|
|
}
|
|
|
|
std::string CborMessageStatusToString(CborMessageStatus status) {
|
|
switch (status) {
|
|
case kCborUninitialized:
|
|
return "Uninitialized";
|
|
case kCborParseOk:
|
|
return "ParseOk";
|
|
case kCborParseError:
|
|
return "ParseError";
|
|
case kCborValidateOk:
|
|
return "ValidateOk";
|
|
case kCborValidateWarning:
|
|
return "ValidateWarning";
|
|
case kCborValidateError:
|
|
return "ValidateError";
|
|
case kCborValidateFatal:
|
|
return "ValidateFatal";
|
|
}
|
|
return "undefined status";
|
|
}
|
|
|
|
void CborValidator::Reset() {
|
|
message_status_ = kCborUninitialized;
|
|
parse_result_ = {nullptr, nullptr, ""};
|
|
validate_messages_.clear();
|
|
}
|
|
|
|
CborMessageStatus CborValidator::Parse(const std::vector<uint8_t>& cbor) {
|
|
Reset();
|
|
parse_result_ = cppbor::parse(cbor);
|
|
message_status_ =
|
|
(std::get<0>(parse_result_) && std::get<2>(parse_result_).empty())
|
|
? kCborParseOk
|
|
: kCborParseError;
|
|
return message_status_;
|
|
}
|
|
|
|
const cppbor::ParseResult* CborValidator::GetParseResult() const {
|
|
if (message_status_ == kCborUninitialized) {
|
|
return nullptr;
|
|
}
|
|
return &parse_result_;
|
|
}
|
|
|
|
std::string CborValidator::GetRawMessage() const {
|
|
if (message_status_ == kCborUninitialized ||
|
|
message_status_ == kCborParseError) {
|
|
return std::string();
|
|
}
|
|
const cppbor::Item* parsed_item = std::get<0>(parse_result_).get();
|
|
if (parsed_item == nullptr) {
|
|
return "<null>";
|
|
}
|
|
return cppbor::prettyPrint(parsed_item);
|
|
}
|
|
|
|
CborMessageStatus CborValidator::Validate() {
|
|
if (message_status_ != kCborParseOk) return message_status_;
|
|
// No other validations to be done than Parse() being successful.
|
|
AddValidationMessage(kCborValidateOk, "No validations are done.");
|
|
return message_status_;
|
|
}
|
|
|
|
std::string CborValidator::GetFormattedMessage() const {
|
|
return GetRawMessage();
|
|
}
|
|
|
|
void CborValidator::AddValidationMessage(CborMessageStatus status,
|
|
const std::string& msg) {
|
|
validate_messages_.push_back({status, msg});
|
|
if (status > message_status_) message_status_ = status;
|
|
}
|
|
|
|
// TODO(b/314141962): Replace this with the map lookup function in cppbor
|
|
// library
|
|
const cppbor::Item* CborValidator::GetMapEntry(const cppbor::Map& map,
|
|
const std::string& entry_name) {
|
|
for (auto const& entry : map) {
|
|
if (!entry.first->asTstr()) continue;
|
|
const std::string& name = entry.first->asTstr()->value();
|
|
if (name == entry_name) return entry.second.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::string CborValidator::CheckMapEntry(const cppbor::Map& map,
|
|
cppbor::MajorType major_type,
|
|
const std::string& entry_name) {
|
|
const cppbor::Item* value = GetMapEntry(map, entry_name);
|
|
if (!value) {
|
|
return entry_name + " is missing.";
|
|
}
|
|
if (value->type() != major_type) {
|
|
return entry_name + " has the wrong type. Expect: " +
|
|
CppborMajorTypeToString(major_type) +
|
|
", actual: " + CppborMajorTypeToString(value->type());
|
|
}
|
|
return "";
|
|
}
|
|
} // namespace util
|
|
} // namespace wvoec
|