#include #include using android::base::Error; using android::base::Result; namespace hwtrust { rust::DiceChainKind convertKind(DiceChain::Kind kind) { switch (kind) { case DiceChain::Kind::kVsr13: return rust::DiceChainKind::Vsr13; case DiceChain::Kind::kVsr14: return rust::DiceChainKind::Vsr14; case DiceChain::Kind::kVsr15: return rust::DiceChainKind::Vsr15; case DiceChain::Kind::kVsr16: return rust::DiceChainKind::Vsr16; } } // The public API hides all rust deps from clients, so we end up with opaque, boxed types. This // class standardizes the syntax for dealing with these types. How to... // ...define a boxed opaque type: struct BoxedFoo : Boxed {}; // ...construct an object: auto foo = BoxedFoo::moveFrom(boxed); // ...dereference the inner object: **foo; template class Boxed { public: Boxed(::rust::Box b) : box_(std::move(b)) {} static std::unique_ptr moveFrom(::rust::Box& b) { return std::make_unique(std::move(b)); } const BoxedT &operator*() const noexcept { return *box_; } BoxedT &operator*() noexcept { return *box_; } private: ::rust::Box box_; }; // Definition of the forward-declared boxed types. struct BoxedDiceChain : Boxed {}; struct BoxedCsr : Boxed {}; // Define to satisfy unique_ptr. DiceChain::~DiceChain() {} DiceChain::DiceChain(std::unique_ptr chain, size_t size) noexcept : chain_(std::move(chain)), size_(size) {} Result DiceChain::Verify( const std::vector& chain, DiceChain::Kind kind, bool allow_any_mode, std::string_view instance) noexcept { rust::DiceChainKind chainKind = convertKind(kind); auto res = rust::VerifyDiceChain( {chain.data(), chain.size()}, chainKind, allow_any_mode, instance.data()); if (!res.error.empty()) { return Error() << static_cast(res.error); } return DiceChain(BoxedDiceChain::moveFrom(res.chain), res.len); } Result>> DiceChain::CosePublicKeys() const noexcept { std::vector> result; for (auto i = 0; i < size_; ++i) { auto key = rust::GetDiceChainPublicKey(**chain_, i); if (key.empty()) { return Error() << "Failed to get public key from chain entry " << i; } result.emplace_back(key.begin(), key.end()); } return result; } bool DiceChain::IsProper() const noexcept { return rust::IsDiceChainProper(**chain_); } // Define with a full definition of BoxedCsr to satisfy unique_ptr. Csr::~Csr() {} Csr::Csr(std::unique_ptr csr, DiceChain::Kind kind, std::string_view instance) noexcept : mCsr(std::move(csr)), mKind(kind), mInstance(instance.data()) {} Result Csr::validate(const std::vector& request, DiceChain::Kind kind, bool allowAnyMode, std::string_view instance) noexcept { rust::DiceChainKind chainKind = convertKind(kind); auto result = rust::validateCsr( {request.data(), request.size()}, chainKind, allowAnyMode, instance.data()); if (!result.error.empty()) { return Error() << static_cast(result.error); } return Csr(BoxedCsr::moveFrom(result.csr), kind, instance); } Result Csr::getDiceChain() const noexcept { auto result = rust::getDiceChainFromCsr(**mCsr); if (!result.error.empty()) { return Error() << static_cast(result.error); } return DiceChain(BoxedDiceChain::moveFrom(result.chain), result.len); } } // namespace hwtrust