/* ** ** 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 #include #include #include #include #include #include #include #include #include #include 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, keymaster_error_t> decodeData(const std::vector& response); template bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); template bool getUint64(const std::unique_ptr& item, T& value); bool getSharedSecretParameters(const std::unique_ptr& item, const uint32_t pos, SharedSecretParameters& params); bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, string& value); bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, vector& value); bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, vector& keyParams); bool addKeyparameters(Array& array, const vector& keyParams); bool addAttestationKey(Array& array, const std::optional& attestationKey); bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken); bool addSharedSecretParameters(Array& array, const vector& params); bool getTimeStampToken(const std::unique_ptr& item, const uint32_t pos, TimeStampToken& token); bool getKeyCharacteristics(const std::unique_ptr& item, const uint32_t pos, vector& keyCharacteristics); bool getCertificateChain(const std::unique_ptr& item, const uint32_t pos, vector& keyCharacteristics); bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, vector>& data); bool addTimeStampToken(Array& array, const TimeStampToken& token); bool getMapItem(const std::unique_ptr& item, const uint32_t pos, Map& map); bool getArrayItem(const std::unique_ptr& item, const uint32_t pos, Array& array); inline bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, keymaster_error_t& errorCode) { uint64_t errorVal; if (!getUint64(item, pos, errorVal)) { return false; } errorCode = static_cast(0 - errorVal); return true; } private: /** * Returns the negative value of the same number. */ inline int32_t get2sCompliment(uint32_t value) { return static_cast(~value + 1); } /** * Get the type of the Item pointer. */ inline MajorType getType(const unique_ptr& 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&> pair, vector& keyParam); /** * Get the sub item pointer from the root item pointer at the given position. */ inline void getItemAtPos(const unique_ptr& item, const uint32_t pos, unique_ptr& subItem) { Array* arr = nullptr; if (MajorType::ARRAY != getType(item)) { return; } arr = const_cast(item.get()->asArray()); if (arr->size() < (pos + 1)) { return; } subItem = std::move((*arr)[pos]); } }; template bool CborConverter::getUint64(const unique_ptr& item, T& value) { bool ret = false; if ((item == nullptr) || (std::is_unsigned::value && (MajorType::UINT != getType(item))) || ((std::is_signed::value && (MajorType::NINT != getType(item))))) { return ret; } if (std::is_unsigned::value) { const Uint* uintVal = item.get()->asUint(); value = static_cast(uintVal->value()); } else { const Nint* nintVal = item.get()->asNint(); value = static_cast(nintVal->value()); } ret = true; return ret; // success } template bool CborConverter::getUint64(const unique_ptr& item, const uint32_t pos, T& value) { unique_ptr intItem(nullptr); getItemAtPos(item, pos, intItem); return getUint64(intItem, value); } } // namespace keymint::javacard