Implement GetKeyCharacteristics.
Still need to add serialization to the messages.
Change-Id: I572c48474bf4d4f553d53cad475b57fa8937a02a
diff --git a/authorization_set.cpp b/authorization_set.cpp
index 1fb9d82..35a12b2 100644
--- a/authorization_set.cpp
+++ b/authorization_set.cpp
@@ -33,35 +33,7 @@
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_);
- for (size_t i = 0; i < elems_size_; ++i) {
- if (is_blob_tag(elems_[i].tag))
- elems_[i].blob.data = indirect_data_ + (elems_[i].blob.data - set.indirect_data_);
- }
-
- indirect_data_size_ = set.indirect_data_size_;
- indirect_data_capacity_ = indirect_data_size_;
- }
- error_ = OK;
+ Reinitialize(set.elems_, set.elems_size_);
}
AuthorizationSet::~AuthorizationSet() {
@@ -105,7 +77,6 @@
}
keymaster_key_param_t empty;
-
keymaster_key_param_t AuthorizationSet::operator[](int at) const {
if (at < (int)elems_size_) {
return elems_[at];
@@ -114,6 +85,60 @@
return empty;
}
+template <typename T> int comparator(const T& a, const T& b) {
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+}
+
+static int param_comparator(const void* a, const void* b) {
+ const keymaster_key_param_t* lhs = static_cast<const keymaster_key_param_t*>(a);
+ const keymaster_key_param_t* rhs = static_cast<const keymaster_key_param_t*>(b);
+
+ if (lhs->tag < rhs->tag)
+ return -1;
+ else if (lhs->tag > rhs->tag)
+ return 1;
+ else
+ switch (keymaster_tag_get_type(lhs->tag)) {
+ default:
+ case KM_INVALID:
+ return 0;
+ case KM_ENUM:
+ case KM_ENUM_REP:
+ return comparator(lhs->enumerated, rhs->enumerated);
+ case KM_INT:
+ case KM_INT_REP:
+ return comparator(lhs->integer, rhs->integer);
+ case KM_LONG:
+ return comparator(lhs->long_integer, rhs->long_integer);
+ case KM_DATE:
+ return comparator(lhs->date_time, rhs->date_time);
+ case KM_BOOL:
+ return comparator(lhs->boolean, rhs->boolean);
+ case KM_BIGNUM:
+ case KM_BYTES: {
+ size_t min_len = lhs->blob.data_length;
+ if (rhs->blob.data_length < min_len)
+ min_len = rhs->blob.data_length;
+
+ if (lhs->blob.data_length == rhs->blob.data_length && min_len > 0)
+ return memcmp(lhs->blob.data, rhs->blob.data, min_len);
+ int cmp_result = memcmp(lhs->blob.data, rhs->blob.data, min_len);
+ if (cmp_result == 0) {
+ // The blobs are equal up to the length of the shortest (which may have length 0),
+ // so the shorter is less, the longer is greater and if they have the same length
+ // they're identical.
+ return comparator(lhs->blob.data_length, rhs->blob.data_length);
+ }
+ return cmp_result;
+ } break;
+ }
+}
+
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;