mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Remove authorization set serialization."
This commit is contained in:
@@ -118,279 +118,6 @@ NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
|
|||||||
return data_[pos];
|
return data_[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Persistent format is:
|
|
||||||
* | 32 bit indirect_size |
|
|
||||||
* --------------------------------
|
|
||||||
* | indirect_size bytes of data | this is where the blob data is stored
|
|
||||||
* --------------------------------
|
|
||||||
* | 32 bit element_count | number of entries
|
|
||||||
* | 32 bit elements_size | total bytes used by entries (entries have variable length)
|
|
||||||
* --------------------------------
|
|
||||||
* | elementes_size bytes of data | where the elements are stored
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Persistent format of blobs and bignums:
|
|
||||||
* | 32 bit tag |
|
|
||||||
* | 32 bit blob_length |
|
|
||||||
* | 32 bit indirect_offset |
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct OutStreams {
|
|
||||||
std::ostream& indirect;
|
|
||||||
std::ostream& elements;
|
|
||||||
size_t skipped;
|
|
||||||
};
|
|
||||||
|
|
||||||
OutStreams& serializeParamValue(OutStreams& out, const vector<uint8_t>& blob) {
|
|
||||||
uint32_t buffer;
|
|
||||||
|
|
||||||
// write blob_length
|
|
||||||
auto blob_length = blob.size();
|
|
||||||
if (blob_length > std::numeric_limits<uint32_t>::max()) {
|
|
||||||
out.elements.setstate(std::ios_base::badbit);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
buffer = blob_length;
|
|
||||||
out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
|
|
||||||
|
|
||||||
// write indirect_offset
|
|
||||||
auto offset = out.indirect.tellp();
|
|
||||||
if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
|
|
||||||
uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
|
|
||||||
out.elements.setstate(std::ios_base::badbit);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
buffer = offset;
|
|
||||||
out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
|
|
||||||
|
|
||||||
// write blob to indirect stream
|
|
||||||
if (blob_length) out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
OutStreams& serializeParamValue(OutStreams& out, const T& value) {
|
|
||||||
out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
|
|
||||||
// skip invalid entries.
|
|
||||||
++out.skipped;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
|
|
||||||
out.elements.write(reinterpret_cast<const char*>(¶m.tag), sizeof(int32_t));
|
|
||||||
return serializeParamValue(out, accessTagValue(ttag, param));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
struct choose_serializer;
|
|
||||||
template <typename... Tags>
|
|
||||||
struct choose_serializer<MetaList<Tags...>> {
|
|
||||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
|
||||||
return choose_serializer<Tags...>::serialize(out, param);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct choose_serializer<> {
|
|
||||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
|
||||||
LOG(WARNING) << "Trying to serialize unknown tag " << unsigned(param.tag)
|
|
||||||
<< ". Did you forget to add it to all_tags_t?";
|
|
||||||
++out.skipped;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <TagType tag_type, Tag tag, typename... Tail>
|
|
||||||
struct choose_serializer<android::hardware::security::keymint::TypedTag<tag_type, tag>, Tail...> {
|
|
||||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
|
||||||
if (param.tag == tag) {
|
|
||||||
return android::hardware::security::keymint::serialize(TypedTag<tag_type, tag>(), out,
|
|
||||||
param);
|
|
||||||
} else {
|
|
||||||
return choose_serializer<Tail...>::serialize(out, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
|
||||||
return choose_serializer<all_tags_t>::serialize(out, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
|
|
||||||
std::stringstream indirect;
|
|
||||||
std::stringstream elements;
|
|
||||||
OutStreams streams = {indirect, elements, 0};
|
|
||||||
for (const auto& param : params) {
|
|
||||||
serialize(streams, param);
|
|
||||||
}
|
|
||||||
if (indirect.bad() || elements.bad()) {
|
|
||||||
out.setstate(std::ios_base::badbit);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
auto pos = indirect.tellp();
|
|
||||||
if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
|
|
||||||
out.setstate(std::ios_base::badbit);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
uint32_t indirect_size = pos;
|
|
||||||
pos = elements.tellp();
|
|
||||||
if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
|
|
||||||
out.setstate(std::ios_base::badbit);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
uint32_t elements_size = pos;
|
|
||||||
uint32_t element_count = params.size() - streams.skipped;
|
|
||||||
|
|
||||||
out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
|
|
||||||
|
|
||||||
pos = out.tellp();
|
|
||||||
if (indirect_size) out << indirect.rdbuf();
|
|
||||||
assert(out.tellp() - pos == indirect_size);
|
|
||||||
|
|
||||||
out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
|
|
||||||
out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
|
|
||||||
|
|
||||||
pos = out.tellp();
|
|
||||||
if (elements_size) out << elements.rdbuf();
|
|
||||||
assert(out.tellp() - pos == elements_size);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InStreams {
|
|
||||||
std::istream& indirect;
|
|
||||||
std::istream& elements;
|
|
||||||
size_t invalids;
|
|
||||||
};
|
|
||||||
|
|
||||||
InStreams& deserializeParamValue(InStreams& in, vector<uint8_t>* blob) {
|
|
||||||
uint32_t blob_length = 0;
|
|
||||||
uint32_t offset = 0;
|
|
||||||
in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
|
|
||||||
blob->resize(blob_length);
|
|
||||||
in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
|
|
||||||
in.indirect.seekg(offset);
|
|
||||||
in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
InStreams& deserializeParamValue(InStreams& in, T* value) {
|
|
||||||
in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
|
|
||||||
// there should be no invalid KeyParameters but if handle them as zero sized.
|
|
||||||
++in.invalids;
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
|
|
||||||
return deserializeParamValue(in, &accessTagValue(ttag, *param));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
struct choose_deserializer;
|
|
||||||
template <typename... Tags>
|
|
||||||
struct choose_deserializer<MetaList<Tags...>> {
|
|
||||||
static InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
|
||||||
return choose_deserializer<Tags...>::deserialize(in, param);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct choose_deserializer<> {
|
|
||||||
static InStreams& deserialize(InStreams& in, KeyParameter*) {
|
|
||||||
// encountered an unknown tag -> fail parsing
|
|
||||||
in.elements.setstate(std::ios_base::badbit);
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <TagType tag_type, Tag tag, typename... Tail>
|
|
||||||
struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
|
|
||||||
static InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
|
||||||
if (param->tag == tag) {
|
|
||||||
return android::hardware::security::keymint::deserialize(TypedTag<tag_type, tag>(), in,
|
|
||||||
param);
|
|
||||||
} else {
|
|
||||||
return choose_deserializer<Tail...>::deserialize(in, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
|
||||||
in.elements.read(reinterpret_cast<char*>(¶m->tag), sizeof(Tag));
|
|
||||||
return choose_deserializer<all_tags_t>::deserialize(in, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
|
|
||||||
uint32_t indirect_size = 0;
|
|
||||||
in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
|
|
||||||
std::string indirect_buffer(indirect_size, '\0');
|
|
||||||
if (indirect_buffer.size() != indirect_size) {
|
|
||||||
in.setstate(std::ios_base::badbit);
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
in.read(&indirect_buffer[0], indirect_buffer.size());
|
|
||||||
|
|
||||||
uint32_t element_count = 0;
|
|
||||||
in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
|
|
||||||
uint32_t elements_size = 0;
|
|
||||||
in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
|
|
||||||
|
|
||||||
std::string elements_buffer(elements_size, '\0');
|
|
||||||
if (elements_buffer.size() != elements_size) {
|
|
||||||
in.setstate(std::ios_base::badbit);
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
in.read(&elements_buffer[0], elements_buffer.size());
|
|
||||||
|
|
||||||
if (in.bad()) return in;
|
|
||||||
|
|
||||||
// TODO write one-shot stream buffer to avoid copying here
|
|
||||||
std::stringstream indirect(indirect_buffer);
|
|
||||||
std::stringstream elements(elements_buffer);
|
|
||||||
InStreams streams = {indirect, elements, 0};
|
|
||||||
|
|
||||||
params->resize(element_count);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < element_count; ++i) {
|
|
||||||
deserialize(streams, &(*params)[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are legacy blobs which have invalid tags in them due to a bug during serialization.
|
|
||||||
* This makes sure that invalid tags are filtered from the result before it is returned.
|
|
||||||
*/
|
|
||||||
if (streams.invalids > 0) {
|
|
||||||
std::vector<KeyParameter> filtered(element_count - streams.invalids);
|
|
||||||
auto ifiltered = filtered.begin();
|
|
||||||
for (auto& p : *params) {
|
|
||||||
if (p.tag != Tag::INVALID) {
|
|
||||||
*ifiltered++ = std::move(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*params = std::move(filtered);
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AuthorizationSet::Serialize(std::ostream* out) const {
|
|
||||||
serialize(*out, data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AuthorizationSet::Deserialize(std::istream* in) {
|
|
||||||
deserialize(*in, &data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
|
AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
|
||||||
uint64_t public_exponent) {
|
uint64_t public_exponent) {
|
||||||
Authorization(TAG_ALGORITHM, Algorithm::RSA);
|
Authorization(TAG_ALGORITHM, Algorithm::RSA);
|
||||||
|
|||||||
@@ -32,9 +32,8 @@ using std::vector;
|
|||||||
class AuthorizationSetBuilder;
|
class AuthorizationSetBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ordered collection of KeyParameters. It provides memory ownership and some convenient
|
* A collection of KeyParameters. It provides memory ownership and some convenient functionality for
|
||||||
* functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters.
|
* sorting, deduplicating, joining, and subtracting sets of KeyParameters.
|
||||||
* For serialization, wrap the backing store of this structure in a vector<KeyParameter>.
|
|
||||||
*/
|
*/
|
||||||
class AuthorizationSet {
|
class AuthorizationSet {
|
||||||
public:
|
public:
|
||||||
@@ -219,9 +218,6 @@ class AuthorizationSet {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serialize(std::ostream* out) const;
|
|
||||||
void Deserialize(std::istream* in);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NullOr<const KeyParameter&> GetEntry(Tag tag) const;
|
NullOr<const KeyParameter&> GetEntry(Tag tag) const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user