Eliminate in-place serialization.

Not doing in-place serialization will result in greater heap
consumption, but eliminates many alignment-related issues.  Given more
time, I'd prefer to solve the alignment issues by computing and
inserting appropriate padding, but we don't have the time.

Change-Id: I86e4bdf57263db26c73372ae2963f21c5f5f00aa
diff --git a/authorization_set.cpp b/authorization_set.cpp
index 94a69e8..4ccd3f1 100644
--- a/authorization_set.cpp
+++ b/authorization_set.cpp
@@ -30,10 +30,36 @@
 
 const size_t STARTING_ELEMS_CAPACITY = 8;
 
-AuthorizationSet::~AuthorizationSet() {
-    FreeData();
+AuthorizationSet::AuthorizationSet(const AuthorizationSet& set)
+    : elems_(NULL), indirect_data_(NULL) {
+    elems_ = new keymaster_key_param_t[set.elems_size_];
+    if (elems_ == NULL) {
+        error_ = ALLOCATION_FAILURE;
+        return;
+    }
+    memcpy(elems_, set.elems_, set.elems_size_ * sizeof(keymaster_key_param_t));
+    elems_size_ = set.elems_size_;
+    elems_capacity_ = elems_size_;
+
+    if (set.indirect_data_ == NULL) {
+        indirect_data_ = NULL;
+        indirect_data_size_ = 0;
+        indirect_data_capacity_ = 0;
+    } else {
+        indirect_data_ = new uint8_t[set.indirect_data_size_];
+        if (indirect_data_ == NULL) {
+            error_ = ALLOCATION_FAILURE;
+            return;
+        }
+        memcpy(indirect_data_, set.indirect_data_, set.indirect_data_size_);
+        indirect_data_size_ = set.indirect_data_size_;
+        indirect_data_capacity_ = indirect_data_size_;
+    }
+    error_ = OK;
 }
 
+AuthorizationSet::~AuthorizationSet() { FreeData(); }
+
 bool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) {
     FreeData();
 
@@ -41,7 +67,7 @@
     elems_capacity_ = count;
     indirect_data_size_ = ComputeIndirectDataSize(elems, count);
     indirect_data_capacity_ = indirect_data_size_;
-    error_ = OK_GROWABLE;
+    error_ = OK;
 
     indirect_data_ = new uint8_t[indirect_data_size_];
     elems_ = new keymaster_key_param_t[elems_size_];
@@ -49,7 +75,6 @@
         set_invalid(ALLOCATION_FAILURE);
         return false;
     }
-    owns_data_ = true;
 
     memcpy(elems_, elems, sizeof(keymaster_key_param_t) * elems_size_);
     CopyIndirectData();
@@ -57,28 +82,6 @@
     return true;
 }
 
-AuthorizationSet::AuthorizationSet(uint8_t* serialized_set, size_t length) : owns_data_(false) {
-    if (!DeserializeInPlace(&serialized_set, serialized_set + length))
-        set_invalid(MALFORMED_DATA);
-}
-
-void AuthorizationSet::Reinitialize(keymaster_key_param_t* elems_array, size_t elems_buf_count,
-                                    uint8_t* indirect_data_buf, size_t indirect_data_buf_size) {
-    FreeData();
-
-    elems_ = elems_array;
-    elems_size_ = 0;
-    elems_capacity_ = elems_buf_count;
-    indirect_data_ = indirect_data_buf;
-    indirect_data_size_ = 0;
-    indirect_data_capacity_ = indirect_data_buf_size;
-    owns_data_ = false;
-
-    if (CheckIndirectDataOffsets()) {
-        error_ = OK_GROWABLE;
-    }
-}
-
 void AuthorizationSet::set_invalid(Error error) {
     error_ = error;
     FreeData();
@@ -111,101 +114,61 @@
 
 bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
     if (elems_size_ >= elems_capacity_) {
-        if (owns_data_) {
-            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);
-                return false;
-            }
-            memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
-            delete[] elems_;
-            elems_ = new_elems;
-            elems_capacity_ = new_capacity;
-        } else {
+        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);
             return false;
         }
+        memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
+        delete[] elems_;
+        elems_ = new_elems;
+        elems_capacity_ = new_capacity;
     }
 
     if (is_blob_tag(elem.tag)) {
         if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) {
-            if (owns_data_) {
-                size_t new_capacity = 2 * (indirect_data_capacity_ + elem.blob.data_length);
-                uint8_t* new_data = new uint8_t[new_capacity];
-                if (new_data == false) {
-                    set_invalid(ALLOCATION_FAILURE);
-                    return false;
-                }
-                memcpy(new_data, indirect_data_, indirect_data_size_);
-                delete[] indirect_data_;
-                indirect_data_ = new_data;
-                indirect_data_capacity_ = new_capacity;
-            } else {
+            size_t new_capacity = 2 * (indirect_data_capacity_ + elem.blob.data_length);
+            uint8_t* new_data = new uint8_t[new_capacity];
+            if (new_data == false) {
+                set_invalid(ALLOCATION_FAILURE);
                 return false;
             }
+            memcpy(new_data, indirect_data_, indirect_data_size_);
+            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 = reinterpret_cast<uint8_t*>(indirect_data_size_);
         indirect_data_size_ += elem.blob.data_length;
     }
 
     elems_[elems_size_++] = elem;
-
-    if (elems_size_ == elems_capacity_ && !owns_data_) {
-        error_ = OK_FULL;
-    }
     return true;
 }
 
-uint8_t* AuthorizationSet::Serialize(uint8_t* serialized_set) const {
+size_t AuthorizationSet::SerializedSize() const {
+    return sizeof(uint32_t) +                 // Length of elems_
+           (sizeof(*elems_) * elems_size_) +  // elems_
+           sizeof(uint32_t) +                 // Length of indirect data
+           indirect_data_size_;               // Indirect data
+}
+
+uint8_t* AuthorizationSet::Serialize(uint8_t* serialized_set, const uint8_t* end) const {
     serialized_set =
-        append_size_and_data_to_buf(serialized_set, elems_, elems_size_ * sizeof(*elems_));
-    return append_size_and_data_to_buf(serialized_set, indirect_data_, indirect_data_size_);
+        append_size_and_data_to_buf(serialized_set, end, elems_, elems_size_ * sizeof(*elems_));
+    return append_size_and_data_to_buf(serialized_set, end, indirect_data_, indirect_data_size_);
 }
 
-bool AuthorizationSet::DeserializeInPlace(uint8_t** buf, const uint8_t* end) {
-    uint32_t elems_buf_size;
-    if (!copy_from_buf(buf, end, &elems_buf_size) ||
-        (elems_buf_size % sizeof(keymaster_key_param_t)) != 0 || end < (*buf + elems_buf_size)) {
-        return false;
-    }
-
-    keymaster_key_param_t* elems = reinterpret_cast<keymaster_key_param_t*>(*buf);
-    *buf += elems_buf_size;
-
-    uint32_t indirect_size;
-    if (!copy_from_buf(buf, end, &indirect_size) ||
-        indirect_size !=
-        ComputeIndirectDataSize(elems, elems_buf_size / sizeof(keymaster_key_param_t)))
-        return false;
-
-    uint8_t* indirect_data = *buf;
-    *buf += indirect_size;
-
+bool AuthorizationSet::Deserialize(const uint8_t** buf, const uint8_t* end) {
     FreeData();
 
-    owns_data_ = false;
-    elems_ = elems;
-    elems_size_ = elems_buf_size / sizeof(keymaster_key_param_t);
-    elems_capacity_ = elems_size_;
-    indirect_data_ = indirect_data;
-    indirect_data_size_ = indirect_size;
-    indirect_data_capacity_ = indirect_size;
-
-    if (CheckIndirectDataOffsets()) {
-        error_ = OK_FULL;
-        return true;
-    }
-    return false;
-}
-
-bool AuthorizationSet::DeserializeToCopy(const uint8_t** buf, const uint8_t* end) {
-    FreeData();
-    owns_data_ = true;
-
     uint32_t elems_buf_size;
     if (!copy_from_buf(buf, end, &elems_buf_size) ||
         (elems_buf_size % sizeof(keymaster_key_param_t)) != 0 || end < (*buf + elems_buf_size)) {
+        set_invalid(MALFORMED_DATA);
         return false;
     }
 
@@ -220,8 +183,10 @@
     uint32_t indirect_size;
     if (!copy_from_buf(buf, end, &indirect_size) ||
         indirect_size !=
-        ComputeIndirectDataSize(elems_, elems_buf_size / sizeof(keymaster_key_param_t)))
+            ComputeIndirectDataSize(elems_, elems_buf_size / sizeof(keymaster_key_param_t))) {
+        set_invalid(MALFORMED_DATA);
         return false;
+    }
 
     indirect_data_ = new uint8_t[indirect_size];
     if (indirect_data_ == NULL) {
@@ -235,17 +200,20 @@
     elems_capacity_ = elems_size_;
     indirect_data_size_ = indirect_size;
     indirect_data_capacity_ = indirect_size;
-    owns_data_ = true;
-    error_ = OK_GROWABLE;
+    error_ = OK;
 
     return CheckIndirectDataOffsets();
 }
 
 void AuthorizationSet::FreeData() {
-    if (owns_data_) {
-        delete[] elems_;
-        delete[] indirect_data_;
-    }
+    if (elems_ != NULL)
+        memset(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t));
+    if (indirect_data_ != NULL)
+        memset(indirect_data_, 0, indirect_data_size_);
+
+    delete[] elems_;
+    delete[] indirect_data_;
+
     elems_ = NULL;
     indirect_data_ = NULL;
     elems_size_ = 0;