Added AuthorizationSet push_back method that takes a set.
This is needed for some key refactoring work. Also did some
AuthorizationSet refactoring here.
Change-Id: I681a2793838c1d68b22dc2a39258c30d7ab117bc
diff --git a/authorization_set.cpp b/authorization_set.cpp
index a0ca571..2b65ee1 100644
--- a/authorization_set.cpp
+++ b/authorization_set.cpp
@@ -40,30 +40,61 @@
FreeData();
}
+bool AuthorizationSet::reserve_elems(size_t count) {
+ if (count >= elems_capacity_) {
+ keymaster_key_param_t* new_elems = new keymaster_key_param_t[count];
+ if (new_elems == NULL) {
+ set_invalid(ALLOCATION_FAILURE);
+ return false;
+ }
+ memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
+ delete[] elems_;
+ elems_ = new_elems;
+ elems_capacity_ = count;
+ }
+ return true;
+}
+
+bool AuthorizationSet::reserve_indirect(size_t length) {
+ if (length > indirect_data_capacity_) {
+ uint8_t* new_data = new uint8_t[length];
+ if (new_data == NULL) {
+ set_invalid(ALLOCATION_FAILURE);
+ return false;
+ }
+ memcpy(new_data, indirect_data_, indirect_data_size_);
+
+ // Fix up the data pointers to point into the new region.
+ for (size_t i = 0; i < elems_size_; ++i) {
+ if (is_blob_tag(elems_[i].tag))
+ elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_);
+ }
+ delete[] indirect_data_;
+ indirect_data_ = new_data;
+ indirect_data_capacity_ = length;
+ }
+ return true;
+}
+
bool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) {
FreeData();
- elems_size_ = count;
- elems_capacity_ = count;
- indirect_data_size_ = ComputeIndirectDataSize(elems, count);
- indirect_data_capacity_ = indirect_data_size_;
- error_ = OK;
-
- indirect_data_ = new uint8_t[indirect_data_size_];
- elems_ = new keymaster_key_param_t[elems_size_];
- if (indirect_data_ == NULL || elems_ == NULL) {
- set_invalid(ALLOCATION_FAILURE);
+ if (!reserve_elems(count))
return false;
- }
- memcpy(elems_, elems, sizeof(keymaster_key_param_t) * elems_size_);
+ if (!reserve_indirect(ComputeIndirectDataSize(elems, count)))
+ return false;
+
+ memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count);
+ elems_size_ = count;
CopyIndirectData();
+ error_ = OK;
return true;
}
void AuthorizationSet::set_invalid(Error error) {
- error_ = error;
FreeData();
+ error_ = error;
}
int AuthorizationSet::find(keymaster_tag_t tag, int begin) const {
@@ -139,38 +170,29 @@
}
}
-bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
- if (elems_size_ >= elems_capacity_) {
- size_t new_capacity = elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY;
- keymaster_key_param_t* new_elems = new keymaster_key_param_t[new_capacity];
- if (new_elems == NULL) {
- set_invalid(ALLOCATION_FAILURE);
+bool AuthorizationSet::push_back(const AuthorizationSet& set) {
+ if (!reserve_elems(elems_size_ + set.elems_size_))
+ return false;
+
+ if (!reserve_indirect(indirect_data_size_ + set.indirect_data_size_))
+ return false;
+
+ for (size_t i = 0; i < set.size(); ++i)
+ if (!push_back(set[i]))
return false;
- }
- memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
- delete[] elems_;
- elems_ = new_elems;
- elems_capacity_ = new_capacity;
- }
+
+ return true;
+}
+
+bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
+ if (elems_size_ >= elems_capacity_)
+ if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY))
+ return false;
if (is_blob_tag(elem.tag)) {
- if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) {
- size_t new_capacity = 2 * (indirect_data_capacity_ + elem.blob.data_length);
- uint8_t* new_data = new uint8_t[new_capacity];
- if (new_data == NULL) {
- set_invalid(ALLOCATION_FAILURE);
+ if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length)
+ if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length)))
return false;
- }
- memcpy(new_data, indirect_data_, indirect_data_size_);
- // Fix up the data pointers to point into the new region.
- for (size_t i = 0; i < elems_size_; ++i) {
- if (is_blob_tag(elems_[i].tag))
- elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_);
- }
- delete[] indirect_data_;
- indirect_data_ = new_data;
- indirect_data_capacity_ = new_capacity;
- }
memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length);
elem.blob.data = indirect_data_ + indirect_data_size_;
@@ -306,13 +328,18 @@
return buf;
}
-bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
- FreeData();
+bool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) {
+ if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_data_)) {
+ set_invalid(MALFORMED_DATA);
+ return false;
+ }
+ return true;
+}
+bool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) {
uint32_t elements_count;
uint32_t elements_size;
- if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_data_) ||
- !copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
+ if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
!copy_uint32_from_buf(buf_ptr, end, &elements_size)) {
set_invalid(MALFORMED_DATA);
return false;
@@ -325,11 +352,8 @@
return false;
}
- elems_ = new keymaster_key_param_t[elements_count];
- if (elems_ == NULL) {
- set_invalid(ALLOCATION_FAILURE);
+ if (!reserve_elems(elements_count))
return false;
- }
uint8_t* indirect_end = indirect_data_ + indirect_data_size_;
const uint8_t* elements_end = *buf_ptr + elements_size;
@@ -339,17 +363,20 @@
return false;
}
}
+ elems_size_ = elements_count;
+ return true;
+}
- if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elements_count)) {
+bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+ FreeData();
+
+ if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end))
+ return false;
+
+ if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) {
set_invalid(MALFORMED_DATA);
return false;
}
-
- elems_size_ = elements_count;
- elems_capacity_ = elements_count;
- indirect_data_capacity_ = indirect_data_size_;
- error_ = OK;
-
return true;
}
@@ -368,6 +395,7 @@
elems_capacity_ = 0;
indirect_data_size_ = 0;
indirect_data_capacity_ = 0;
+ error_ = OK;
}
/* static */
@@ -382,18 +410,19 @@
}
void AuthorizationSet::CopyIndirectData() {
- memset(indirect_data_, 0, indirect_data_size_);
+ memset_s(indirect_data_, 0, indirect_data_capacity_);
uint8_t* indirect_data_pos = indirect_data_;
for (size_t i = 0; i < elems_size_; ++i) {
- assert(indirect_data_pos <= indirect_data_ + indirect_data_size_);
+ assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_);
if (is_blob_tag(elems_[i].tag)) {
memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length);
elems_[i].blob.data = indirect_data_pos;
indirect_data_pos += elems_[i].blob.data_length;
}
}
- assert(indirect_data_pos == indirect_data_ + indirect_data_size_);
+ assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_);
+ indirect_data_size_ = indirect_data_pos - indirect_data_;
}
bool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const {