blob: db1033b3e57eacf6f2b596d5539b82ea8f999b7e [file] [log] [blame]
/*
**
** Copyright 2020, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#pragma once
#include <aidl/android/hardware/security/keymint/Certificate.h>
#include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
#include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
#include <aidl/android/hardware/security/sharedsecret/ISharedSecret.h>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <iostream>
#include <keymaster/android_keymaster_messages.h>
#include <memory>
#include <numeric>
#include <vector>
namespace keymint::javacard {
using namespace cppbor;
using namespace aidl::android::hardware::security::keymint;
using namespace aidl::android::hardware::security::secureclock;
using namespace aidl::android::hardware::security::sharedsecret;
using std::string;
using std::unique_ptr;
using std::vector;
class CborConverter {
public:
CborConverter() = default;
~CborConverter() = default;
std::tuple<std::unique_ptr<Item>, keymaster_error_t>
decodeData(const std::vector<uint8_t>& response);
template <typename T>
bool getUint64(const std::unique_ptr<Item>& item, const uint32_t pos, T& value);
template <typename T> bool getUint64(const std::unique_ptr<Item>& item, T& value);
bool getSharedSecretParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
SharedSecretParameters& params);
bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos, string& value);
bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
vector<uint8_t>& value);
bool getHardwareAuthToken(const std::unique_ptr<Item>& item, const uint32_t pos,
HardwareAuthToken& authType);
bool getKeyParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
vector<KeyParameter>& keyParams);
bool addKeyparameters(Array& array, const vector<KeyParameter>& keyParams);
bool addAttestationKey(Array& array, const std::optional<AttestationKey>& attestationKey);
bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken);
bool addSharedSecretParameters(Array& array, const vector<SharedSecretParameters>& params);
bool getTimeStampToken(const std::unique_ptr<Item>& item, const uint32_t pos,
TimeStampToken& token);
bool getKeyCharacteristics(const std::unique_ptr<Item>& item, const uint32_t pos,
vector<KeyCharacteristics>& keyCharacteristics);
bool getCertificateChain(const std::unique_ptr<Item>& item, const uint32_t pos,
vector<Certificate>& keyCharacteristics);
bool getMultiBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
vector<vector<uint8_t>>& data);
bool addTimeStampToken(Array& array, const TimeStampToken& token);
bool getMapItem(const std::unique_ptr<Item>& item, const uint32_t pos,
Map& map);
bool getArrayItem(const std::unique_ptr<Item>& item, const uint32_t pos,
Array& array);
inline bool getErrorCode(const std::unique_ptr<Item>& item, const uint32_t pos,
keymaster_error_t& errorCode) {
uint64_t errorVal;
if (!getUint64<uint64_t>(item, pos, errorVal)) {
return false;
}
errorCode = static_cast<keymaster_error_t>(0 - errorVal);
return true;
}
private:
/**
* Returns the negative value of the same number.
*/
inline int32_t get2sCompliment(uint32_t value) { return static_cast<int32_t>(~value + 1); }
/**
* Get the type of the Item pointer.
*/
inline MajorType getType(const unique_ptr<Item>& item) { return item.get()->type(); }
/**
* Construct Keyparameter structure from the pair of key and value. If TagType is ENUM_REP the
* value contains binary string. If TagType is UINT_REP or ULONG_REP the value contains Array of
* unsigned integers.
*/
bool getKeyParameter(const std::pair<const unique_ptr<Item>&, const unique_ptr<Item>&> pair,
vector<KeyParameter>& keyParam);
/**
* Get the sub item pointer from the root item pointer at the given position.
*/
inline void getItemAtPos(const unique_ptr<Item>& item, const uint32_t pos,
unique_ptr<Item>& subItem) {
Array* arr = nullptr;
if (MajorType::ARRAY != getType(item)) {
return;
}
arr = const_cast<Array*>(item.get()->asArray());
if (arr->size() < (pos + 1)) {
return;
}
subItem = std::move((*arr)[pos]);
}
};
template <typename T> bool CborConverter::getUint64(const unique_ptr<Item>& item, T& value) {
bool ret = false;
if ((item == nullptr) || (std::is_unsigned<T>::value && (MajorType::UINT != getType(item))) ||
((std::is_signed<T>::value && (MajorType::NINT != getType(item))))) {
return ret;
}
if (std::is_unsigned<T>::value) {
const Uint* uintVal = item.get()->asUint();
value = static_cast<T>(uintVal->value());
} else {
const Nint* nintVal = item.get()->asNint();
value = static_cast<T>(nintVal->value());
}
ret = true;
return ret; // success
}
template <typename T>
bool CborConverter::getUint64(const unique_ptr<Item>& item, const uint32_t pos, T& value) {
unique_ptr<Item> intItem(nullptr);
getItemAtPos(item, pos, intItem);
return getUint64(intItem, value);
}
} // namespace keymint::javacard