Files
android/libwvdrmengine/oemcrypto/util/src/cbor_validator.cpp
Cong Lin d8ce542ff9 Add Device info validator to oemcrypto util and unit tests
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
2024-02-22 15:12:37 -08:00

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