aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-10-07 17:32:14 -0400
committerRob Austein <sra@hactrn.net>2016-10-07 17:32:14 -0400
commitdb32574d6c85bb48a2f01d80eec6e241152704ff (patch)
treeb221ddee85010b6eddbed6d23f1b5faeaeaa74a3
parent378bcae718b7b8785b06c8cf82344e4f344a9215 (diff)
Checkpoint along the way to adding keystore attribute support.
This is mostly to archive a commit where PKCS #11 "make test" still works after converting the ks_volatile code to use SDRAM allocated at startup instead of (large) static variables. The attribute code itself is incomplete at this point.
-rw-r--r--Makefile2
-rw-r--r--hal.h33
-rw-r--r--hal_internal.h173
-rw-r--r--ks_attribute.c205
-rw-r--r--ks_flash.c56
-rw-r--r--ks_volatile.c136
-rw-r--r--rpc_api.c50
-rw-r--r--rpc_client.c152
-rw-r--r--rpc_pkey.c94
-rw-r--r--rpc_server.c153
10 files changed, 1003 insertions, 51 deletions
diff --git a/Makefile b/Makefile
index b4c6086..afde6c4 100644
--- a/Makefile
+++ b/Makefile
@@ -118,7 +118,7 @@ endif
#
# The mmap keystore hasn't been rewritten for the new API yet.
-KS_OBJ = ks_index.o ks_volatile.o
+KS_OBJ = ks_index.o ks_attribute.o ks_volatile.o
ifeq "${KS}" "mmap"
KS_OBJ += ks_mmap.o
diff --git a/hal.h b/hal.h
index e94f3b8..5b4de69 100644
--- a/hal.h
+++ b/hal.h
@@ -147,6 +147,7 @@
DEFINE_HAL_ERROR(HAL_ERROR_KEYSTORE_BAD_CRC, "Bad CRC in keystore") \
DEFINE_HAL_ERROR(HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE, "Unsupported keystore block type") \
DEFINE_HAL_ERROR(HAL_ERROR_KEYSTORE_LOST_DATA, "Keystore appears to have lost data") \
+ DEFINE_HAL_ERROR(HAL_ERROR_BAD_ATTRIBUTE_LENGTH, "Bad attribute length") \
END_OF_HAL_ERROR_LIST
/* Marker to forestall silly line continuation errors */
@@ -735,6 +736,8 @@ extern size_t hal_rpc_pkey_get_public_key_len(const hal_pkey_handle_t pkey);
extern hal_error_t hal_rpc_pkey_get_public_key(const hal_pkey_handle_t pkey,
uint8_t *der, size_t *der_len, const size_t der_max);
+#warning Um, why do hal_rpc_pkey_sign() and hal_rpc_pkey_verify() take session arguments?
+
extern hal_error_t hal_rpc_pkey_sign(const hal_session_handle_t session,
const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
@@ -760,6 +763,36 @@ extern hal_error_t hal_rpc_pkey_list(hal_pkey_info_t *result,
const unsigned result_max,
hal_key_flags_t flags);
+typedef struct {
+ uint32_t type;
+ size_t length;
+ const uint8_t *value;
+} hal_rpc_pkey_attribute_t;
+
+extern hal_error_t hal_rpc_pkey_match(const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid);
+
+extern hal_error_t hal_rpc_pkey_set_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len);
+
+extern hal_error_t hal_rpc_pkey_get_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max);
+
+extern hal_error_t hal_rpc_pkey_delete_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type);
+
extern hal_error_t hal_rpc_client_init(void);
extern hal_error_t hal_rpc_client_close(void);
diff --git a/hal_internal.h b/hal_internal.h
index 11f9898..0d40922 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -242,6 +242,30 @@ typedef struct {
const unsigned result_max,
hal_key_flags_t flags);
+ hal_error_t (*match)(const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid);
+
+ hal_error_t (*set_attribute)(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len);
+
+ hal_error_t (*get_attribute)(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max);
+
+ hal_error_t (*delete_attribute)(const hal_pkey_handle_t pkey,
+ const uint32_t type);
+
} hal_rpc_pkey_dispatch_t;
@@ -470,6 +494,35 @@ struct hal_ks_driver {
hal_pkey_info_t *result,
unsigned *result_len,
const unsigned result_max);
+
+ hal_error_t (*match)(hal_ks_t *ks,
+ const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid);
+
+ hal_error_t (*set_attribute)(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len);
+
+ hal_error_t (*get_attribute)(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max);
+
+ hal_error_t (*delete_attribute)(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type);
+
};
@@ -563,6 +616,59 @@ static inline hal_error_t hal_ks_list(hal_ks_t *ks,
return ks->driver->list(ks, result, result_len, result_max);
}
+static inline hal_error_t hal_ks_match(hal_ks_t *ks,
+ const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+ if (ks == NULL || ks->driver == NULL || ks->driver->match == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ return ks->driver->match(ks, type, curve, flags, attributes, attributes_len,
+ result, result_len, result_max, previous_uuid);
+}
+
+static inline hal_error_t hal_ks_set_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+ if (ks == NULL || ks->driver == NULL || ks->driver->set_attribute == NULL || slot == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ return ks->driver->set_attribute(ks, slot, type, value, value_len);
+}
+
+static inline hal_error_t hal_ks_get_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+ if (ks == NULL || ks->driver == NULL || ks->driver->get_attribute == NULL || slot == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ return ks->driver->get_attribute(ks, slot, type, value, value_len, value_max);
+}
+
+static inline hal_error_t hal_ks_delete_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type)
+{
+ if (ks == NULL || ks->driver == NULL || ks->driver->delete_attribute == NULL || slot == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ return ks->driver->delete_attribute(ks, slot, type);
+}
+
/*
* Keystore index. This is intended to be usable by both memory-based
* (in-memory, mmap(), ...) keystores and keystores based on raw flash.
@@ -676,6 +782,69 @@ extern hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi,
int *hint);
/*
+ * Keystore attribute utilities, for use by keystore drivers.
+ *
+ * Basic model here is probably to replace the "der" block in a key
+ * object with a byte array. We could use padding to get alignment,
+ * but it's probably easier just to do this DNS style, pulling a
+ * 16-bit length and 32-bit attribute type out of the byte array
+ * directly. Well, maybe. I guess if we cast the uint8_t* to a
+ * structure pointer we could use the structure to pull out the header
+ * fields, but that has portability issues, particulary if the
+ * compiler gets tetchy about type punning.
+ *
+ * Unclear whether we should treat the key DER specially. Might just
+ * give it an attribute code of 0xFFFFFFFF and treat it same as
+ * everything else, just always first for convenience. This assumes
+ * that PKCS #11 will never use 0xFFFFFFFF, which is a bit risky, but
+ * maybe the code just treats it a little bit specially and knows to
+ * skip over the key DER when looking for attributes, etc.
+ *
+ * We probably don't want to let attributes span block boundaries. We
+ * probably do want to attempt to fit a new attribute into the first
+ * available space which can hold it. In theory, taken together, this
+ * means we will only have to update multiple blocks when required to
+ * add a new block (in which case the max_blocks count changes). Most
+ * of this only applies to flash, for volatile we can use as much
+ * memory as we like, although even there we might want smaller chunks
+ * to avoid wasting huge tracts of space that don't end up being used.
+ * But maybe that's just a configuration thing for the volatile
+ * keystore(s).
+ *
+ * If we have to rewrite a block at all we might as well compact it,
+ * so fragmentation in that sense is a non-issue. Might need to
+ * collapse blocks when deletion has freed up enough space, but that
+ * might be something we handle directly in ks_flash rather than in
+ * the ks_attribute code.
+ *
+ * We need some way of figuring out how many attributes there are.
+ * Options are a marker (like the IPv4 END-OF-OPTIONS option) or a
+ * count in the header. Count is simpler and lets us pre-allocate
+ * arrays so probably go with that.
+ */
+
+extern hal_error_t hal_ks_attribute_scan(const uint8_t * const bytes,
+ const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ size_t *total_len);
+
+extern hal_error_t hal_ks_attribute_delete(uint8_t *bytes,
+ const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes,
+ unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type);
+
+extern hal_error_t hal_ks_attribute_insert(uint8_t *bytes, const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes,
+ unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len);
+
+/*
* RPC lowest-level send and receive routines. These are blocking, and
* transport-specific (sockets, USB).
*/
@@ -725,6 +894,10 @@ typedef enum {
RPC_FUNC_PKEY_VERIFY,
RPC_FUNC_PKEY_LIST,
RPC_FUNC_PKEY_RENAME,
+ RPC_FUNC_PKEY_MATCH,
+ RPC_FUNC_PKEY_SET_ATTRIBUTE,
+ RPC_FUNC_PKEY_GET_ATTRIBUTE,
+ RPC_FUNC_PKEY_DELETE_ATTRIBUTE,
} rpc_func_num_t;
#define RPC_VERSION 0x01010000 /* 1.1.0.0 */
diff --git a/ks_attribute.c b/ks_attribute.c
new file mode 100644
index 0000000..248f98d
--- /dev/null
+++ b/ks_attribute.c
@@ -0,0 +1,205 @@
+/*
+ * ks_attribute.c
+ * --------------
+ * Keystore attribute API. This is internal within libhal.
+ *
+ * Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "hal.h"
+#include "hal_internal.h"
+
+/*
+ * Read and write attribute headers (type and length). We could do
+ * this with a structure type and casts, but that has portability
+ * issues, and doing it this way just isn't expensive enough to worry about.
+ */
+
+#define HEADER_LEN (4 + 2)
+
+static inline hal_error_t read_header(const uint8_t * const bytes, const size_t bytes_len,
+ uint32_t *attribute_type, size_t *attribute_len)
+{
+ if (bytes == NULL || bytes_len < HEADER_LEN || attribute_type == NULL || attribute_len == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ *attribute_type = ((bytes[0] << 24) |
+ (bytes[1] << 16) |
+ (bytes[2] << 8) |
+ (bytes[3] << 0));
+ *attribute_len = ((bytes[4] << 8) |
+ (bytes[5] << 0));
+
+ return HAL_OK;
+}
+
+static inline hal_error_t write_header(uint8_t *bytes, const size_t bytes_len,
+ const uint32_t attribute_type, const size_t attribute_len)
+{
+ if (bytes == NULL || bytes_len < HEADER_LEN)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ bytes[0] = (attribute_type >> 24) & 0xFF;
+ bytes[1] = (attribute_type >> 16) & 0xFF;
+ bytes[2] = (attribute_type >> 8) & 0xFF;
+ bytes[3] = (attribute_type >> 0) & 0xFF;
+ bytes[4] = (attribute_len >> 8) & 0xFF;
+ bytes[5] = (attribute_len >> 0) & 0xFF;
+
+ return HAL_OK;
+}
+
+hal_error_t hal_ks_attribute_scan(const uint8_t * const bytes, const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes, const unsigned attributes_len,
+ size_t *total_len)
+{
+ if (bytes == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ const uint8_t *b = bytes;
+ const uint8_t * const end = bytes + bytes_len;
+
+ for (int i = 0; i < attributes_len; i++) {
+ uint32_t type;
+ size_t length;
+ hal_error_t err = read_header(b, end - b, &type, &length);
+ if (err != HAL_OK)
+ return err;
+ b += HEADER_LEN;
+ if (attributes != NULL) {
+ attributes[i].type = type;
+ attributes[i].length = length;
+ attributes[i].value = b;
+ }
+ b += length;
+ if (b > end)
+ return HAL_ERROR_BAD_ATTRIBUTE_LENGTH;
+ }
+
+ if (total_len != NULL)
+ *total_len = b - bytes;
+
+ return HAL_OK;
+}
+
+/*
+ * Given scan(), delete() and insert() should be relatively simple.
+ *
+ * delete() does a scan to find the attribute it wants to delete, and,
+ * if found, uses memmove() to copy the rest down.
+ *
+ * insert() does a delete to get rid of old value, if any, then does
+ * another scan, checks length what we want to insert against
+ * total_len returned by the scan, and either appends the new
+ * attribute or returns error code saying it couldn't.
+ */
+
+hal_error_t hal_ks_attribute_delete(uint8_t *bytes, const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes, unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type)
+{
+ if (bytes == NULL || attributes == NULL || attributes_len == NULL || total_len == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ int i = 0;
+
+ while (i < *attributes_len && attributes[i].type != type)
+ i++;
+
+ if (i == *attributes_len)
+ return HAL_OK;
+
+ const size_t delete_length = HEADER_LEN + attributes[i].length;
+ const size_t delete_offset = attributes[i].value - HEADER_LEN - bytes;
+
+ if (delete_offset + delete_length > *total_len)
+ return HAL_ERROR_IMPOSSIBLE;
+
+ memmove(bytes + delete_offset,
+ bytes + delete_offset + delete_length,
+ *total_len - delete_length - delete_offset);
+
+ *total_len -= delete_length;
+
+ memmove(&attributes[i], &attributes[i + 1], *attributes_len - i - 1);
+
+ --*attributes_len;
+
+ return HAL_OK;
+}
+
+hal_error_t hal_ks_attribute_insert(uint8_t *bytes, const size_t bytes_len,
+ hal_rpc_pkey_attribute_t *attributes, unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type,
+ const uint8_t * const value, const size_t value_len)
+
+{
+ if (bytes == NULL || attributes == NULL || attributes_len == NULL ||
+ total_len == NULL || value == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ hal_error_t err
+ = hal_ks_attribute_delete(bytes, bytes_len, attributes, attributes_len, total_len, type);
+
+ if (err != HAL_OK)
+ return err;
+
+ if (*total_len + HEADER_LEN + value_len > bytes_len)
+ return HAL_ERROR_RESULT_TOO_LONG;
+
+ uint8_t *b = bytes + *total_len;
+
+ if ((err = write_header(b, bytes_len - *total_len, type, value_len)) != HAL_OK)
+ return err;
+
+ b += HEADER_LEN;
+
+ memcpy(b, value, value_len);
+
+ *total_len += HEADER_LEN + value_len;
+
+ attributes[*attributes_len].type = type;
+ attributes[*attributes_len].length = value_len;
+ attributes[*attributes_len].value = b;
+
+ ++*attributes_len;
+
+ return HAL_OK;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/ks_flash.c b/ks_flash.c
index 475dcde..5b3f718 100644
--- a/ks_flash.c
+++ b/ks_flash.c
@@ -174,10 +174,9 @@ typedef struct {
const static hal_uuid_t pin_uuid = {{0}};
/*
- * The in-memory database almost certainly should be a pointer to
- * allocated SDRAM rather than compile-time data space. Well,
- * the arrays should be, anyway, it might be reasonable to keep
- * the top level structure here. Worry about that later.
+ * The in-memory database structure itself is small, but the arrays it
+ * points to are large enough that they come from SDRAM allocated at
+ * startup.
*/
static db_t db;
@@ -201,7 +200,7 @@ static inline flash_block_status_t block_get_status(const flash_block_t * const
/*
* Pick unused or least-recently-used slot in our in-memory cache.
*
- * Updating lru values is caller's problem: if caller is using cache
+ * Updating lru values is caller's problem: if caller is using a cache
* slot as a temporary buffer and there's no point in caching the
* result, leave the lru values alone and the right thing will happen.
*/
@@ -432,7 +431,6 @@ static hal_error_t block_erase(const unsigned blockno)
/*
* Erase a flash block if it hasn't already been erased.
- * We have to disable fast read for this to work properly.
* May not be necessary, trying to avoid unnecessary wear.
*
* Unclear whether there's any sane reason why this needs to be
@@ -1033,6 +1031,46 @@ static hal_error_t ks_list(hal_ks_t *ks,
return HAL_OK;
}
+static hal_error_t ks_match(hal_ks_t *ks,
+ const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+#warning NIY
+}
+
+static hal_error_t ks_set_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+#warning NIY
+}
+
+static hal_error_t ks_get_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+#warning NIY
+}
+
+static hal_error_t ks_delete_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type)
+{
+#warning NIY
+}
+
const hal_ks_driver_t hal_ks_token_driver[1] = {{
ks_init,
ks_shutdown,
@@ -1041,7 +1079,11 @@ const hal_ks_driver_t hal_ks_token_driver[1] = {{
ks_store,
ks_fetch,
ks_delete,
- ks_list
+ ks_list,
+ ks_match,
+ ks_set_attribute,
+ ks_get_attribute,
+ ks_delete_attribute
}};
/*
diff --git a/ks_volatile.c b/ks_volatile.c
index 29793a4..daaef41 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -48,12 +48,10 @@
#define HAL_STATIC_PKEY_STATE_BLOCKS 0
#endif
-#ifndef HAL_STATIC_KS_VOLATILE_SLOTS
-#define HAL_STATIC_KS_VOLATILE_SLOTS HAL_STATIC_PKEY_STATE_BLOCKS
+#ifndef HAL_KS_VOLATILE_SLOTS
+#define HAL_KS_VOLATILE_SLOTS HAL_STATIC_PKEY_STATE_BLOCKS
#endif
-#if HAL_STATIC_KS_VOLATILE_SLOTS > 0
-
/*
* In-memory keystore database. This should also be usable for
* mmap(), if and when we get around to rewriting that driver (and in
@@ -70,9 +68,7 @@ typedef struct {
typedef struct {
hal_ks_index_t ksi;
- uint16_t _index[HAL_STATIC_KS_VOLATILE_SLOTS];
- hal_ks_name_t _names[HAL_STATIC_KS_VOLATILE_SLOTS];
- ks_key_t keys[HAL_STATIC_KS_VOLATILE_SLOTS];
+ ks_key_t *keys;
} db_t;
/*
@@ -87,7 +83,14 @@ typedef struct {
db_t *db; /* Which memory-based keystore database */
} ks_t;
-static db_t volatile_db;
+/*
+ * If we also supported mmap, there would be a separate definition for
+ * HAL_KS_MMAP_SLOTS above, and the bulk of the code would be under a
+ * conditional testing whether either HAL_KS_*_SLOTS were nonzero.
+ */
+
+#if HAL_KS_VOLATILE_SLOTS > 0
+
static ks_t volatile_ks;
static inline ks_t *ks_to_ksv(hal_ks_t *ks)
@@ -95,9 +98,39 @@ static inline ks_t *ks_to_ksv(hal_ks_t *ks)
return (ks_t *) ks;
}
-static hal_error_t ks_init(db_t *db)
+static inline void *gnaw(uint8_t **mem, size_t *len, const size_t size)
+{
+ if (mem == NULL || *mem == NULL || len == NULL || size > *len)
+ return NULL;
+ void *ret = *mem;
+ *mem += size;
+ *len -= size;
+ return ret;
+}
+
+static hal_error_t ks_init(const hal_ks_driver_t * const driver,
+ ks_t *ksv,
+ uint8_t *mem,
+ size_t len)
{
- assert(db != NULL);
+ if (ksv == NULL || mem == NULL)
+ return HAL_ERROR_IMPOSSIBLE;
+
+ memset(ksv, 0, sizeof(*ksv));
+ memset(mem, 0, len);
+
+ if ((ksv->db = gnaw(&mem, &len, sizeof(*ksv->db))) == NULL ||
+ (ksv->db->ksi.index = gnaw(&mem, &len,
+ sizeof(*ksv->db->ksi.index) * HAL_KS_VOLATILE_SLOTS)) == NULL ||
+ (ksv->db->ksi.names = gnaw(&mem, &len,
+ sizeof(*ksv->db->ksi.names) * HAL_KS_VOLATILE_SLOTS)) == NULL ||
+ (ksv->db->keys = gnaw(&mem, &len,
+ sizeof(*ksv->db->keys) * HAL_KS_VOLATILE_SLOTS)) == NULL)
+ return HAL_ERROR_IMPOSSIBLE;
+
+ ksv->ks.driver = driver;
+ ksv->db->ksi.size = HAL_KS_VOLATILE_SLOTS;
+ ksv->db->ksi.used = 0;
/*
* Set up keystore with empty index and full free list.
@@ -105,34 +138,31 @@ static hal_error_t ks_init(db_t *db)
* just populate the free list in block numerical order.
*/
- db->ksi.size = HAL_STATIC_KS_VOLATILE_SLOTS;
- db->ksi.used = 0;
- db->ksi.index = db->_index;
- db->ksi.names = db->_names;
-
- for (int i = 0; i < HAL_STATIC_KS_VOLATILE_SLOTS; i++)
- db->_index[i] = i;
+ for (int i = 0; i < HAL_KS_VOLATILE_SLOTS; i++)
+ ksv->db->ksi.index[i] = i;
- const hal_error_t err = hal_ks_index_setup(&db->ksi);
-
- if (err != HAL_OK)
- db->ksi.size = 0; /* Mark uninitialized if setup failed */
-
- return err;
+ return hal_ks_index_setup(&ksv->db->ksi);
}
static hal_error_t ks_volatile_init(const hal_ks_driver_t * const driver)
{
- volatile_ks.ks.driver = driver;
- volatile_ks.db = &volatile_db;
- return ks_init(volatile_ks.db);
+ const size_t len = (sizeof(*volatile_ks.db) +
+ sizeof(*volatile_ks.db->ksi.index) * HAL_KS_VOLATILE_SLOTS +
+ sizeof(*volatile_ks.db->ksi.names) * HAL_KS_VOLATILE_SLOTS +
+ sizeof(*volatile_ks.db->keys) * HAL_KS_VOLATILE_SLOTS);
+
+ uint8_t *mem = hal_allocate_static_memory(len);
+
+ if (mem == NULL)
+ return HAL_ERROR_ALLOCATION_FAILURE;
+
+ return ks_init(driver, &volatile_ks, mem, len);
}
static hal_error_t ks_volatile_shutdown(const hal_ks_driver_t * const driver)
{
if (volatile_ks.ks.driver != driver)
return HAL_ERROR_KEYSTORE_ACCESS;
- memset(&volatile_ks, 0, sizeof(volatile_ks));
return HAL_OK;
}
@@ -303,6 +333,50 @@ static hal_error_t ks_list(hal_ks_t *ks,
return HAL_OK;
}
+static hal_error_t ks_match(hal_ks_t *ks,
+ const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+#warning NIY
+ return HAL_ERROR_IMPOSSIBLE;
+}
+
+static hal_error_t ks_set_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+#warning NIY
+ return HAL_ERROR_IMPOSSIBLE;
+}
+
+static hal_error_t ks_get_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+#warning NIY
+ return HAL_ERROR_IMPOSSIBLE;
+}
+
+static hal_error_t ks_delete_attribute(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint32_t type)
+{
+#warning NIY
+ return HAL_ERROR_IMPOSSIBLE;
+}
+
const hal_ks_driver_t hal_ks_volatile_driver[1] = {{
ks_volatile_init,
ks_volatile_shutdown,
@@ -311,10 +385,14 @@ const hal_ks_driver_t hal_ks_volatile_driver[1] = {{
ks_store,
ks_fetch,
ks_delete,
- ks_list
+ ks_list,
+ ks_match,
+ ks_set_attribute,
+ ks_get_attribute,
+ ks_delete_attribute
}};
-#endif /* HAL_STATIC_KS_VOLATILE_SLOTS > 0 */
+#endif /* HAL_KS_VOLATILE_SLOTS > 0 */
/*
* Local variables:
diff --git a/rpc_api.c b/rpc_api.c
index a8dc89d..022dc62 100644
--- a/rpc_api.c
+++ b/rpc_api.c
@@ -338,6 +338,56 @@ hal_error_t hal_rpc_pkey_list(hal_pkey_info_t *result,
return hal_rpc_pkey_dispatch->list(result, result_len, result_max, flags);
}
+hal_error_t hal_rpc_pkey_match(const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+ if ((attributes == NULL && attributes_len > 0) || previous_uuid == NULL ||
+ result == NULL || result_len == NULL || result_max == 0)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (attributes != NULL)
+ for (int i = 0; i < attributes_len; i++)
+ if (attributes[i].value == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ return hal_rpc_pkey_dispatch->match(type, curve, flags, attributes, attributes_len,
+ result, result_len, result_max, previous_uuid);
+}
+
+hal_error_t hal_rpc_pkey_set_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+ if (value == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+ return hal_rpc_pkey_dispatch->set_attribute(pkey, type, value, value_len);
+}
+
+hal_error_t hal_rpc_pkey_get_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+ if (value == NULL || value_len == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+ return hal_rpc_pkey_dispatch->get_attribute(pkey, type, value, value_len, value_max);
+}
+
+hal_error_t hal_rpc_pkey_delete_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type)
+{
+ return hal_rpc_pkey_dispatch->delete_attribute(pkey, type);
+}
+
/*
* Local variables:
* indent-tabs-mode: nil
diff --git a/rpc_client.c b/rpc_client.c
index b4184d4..a56052d 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -740,7 +740,8 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session,
return rpc_ret;
}
-static hal_error_t hal_xdr_decode_pkey_info(const uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_info_t *info)
+static hal_error_t hal_xdr_decode_pkey_info(const uint8_t **iptr, const uint8_t * const ilimit,
+ hal_pkey_info_t *info)
{
uint32_t u32;
@@ -778,10 +779,9 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result,
check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
if (rpc_ret == HAL_OK) {
- int i;
check(hal_xdr_decode_int(&iptr, ilimit, &len));
*result_len = len;
- for (i = 0; i < len; ++i) {
+ for (int i = 0; i < len; ++i) {
if ((ret = hal_xdr_decode_pkey_info(&iptr, ilimit, &result[i])) != HAL_OK) {
*result_len = 0;
return ret;
@@ -791,6 +791,140 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result,
return rpc_ret;
}
+static hal_error_t pkey_remote_match(const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+ size_t attributes_buffer_len = 0;
+ if (attributes != NULL)
+ for (int i = 0; i < attributes_len; i++)
+ attributes_buffer_len += attributes[i].length;
+
+ uint8_t outbuf[nargs(8 + attributes_len * 2) + pad(attributes_buffer_len) + pad(sizeof(hal_uuid_t))];
+ uint8_t *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
+ uint8_t inbuf[nargs(5) + pad(result_max * sizeof(hal_uuid_t)) + pad(sizeof(hal_uuid_t))];
+ const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf);
+ hal_client_handle_t dummy_client = {0};
+ hal_error_t rpc_ret;
+
+ check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_MATCH));
+ check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
+ check(hal_xdr_encode_int(&optr, olimit, type));
+ check(hal_xdr_encode_int(&optr, olimit, curve));
+ check(hal_xdr_encode_int(&optr, olimit, flags));
+ check(hal_xdr_encode_int(&optr, olimit, attributes_len));
+ if (attributes != NULL) {
+ for (int i = 0; i < attributes_len; i++) {
+ check(hal_xdr_encode_int(&optr, olimit, attributes[i].type));
+ check(hal_xdr_encode_buffer(&optr, olimit, attributes[i].value, attributes[i].length));
+ }
+ }
+ check(hal_xdr_encode_int(&optr, olimit, result_max));
+ check(hal_xdr_encode_buffer(&optr, olimit, previous_uuid->uuid, sizeof(previous_uuid->uuid)));
+ check(hal_rpc_send(outbuf, optr - outbuf));
+
+ check(read_matching_packet(RPC_FUNC_PKEY_MATCH, inbuf, sizeof(inbuf), &iptr, &ilimit));
+
+ check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
+ if (rpc_ret == HAL_OK) {
+ uint32_t array_len, uuid_len;
+ *result_len = 0;
+ check(hal_xdr_decode_int(&iptr, ilimit, &array_len));
+ for (int i = 0; i < array_len; ++i) {
+ check(hal_xdr_decode_buffer(&iptr, ilimit, result[i].uuid, &uuid_len));
+ if (uuid_len != sizeof(result[i].uuid))
+ return HAL_ERROR_KEY_NAME_TOO_LONG;
+ }
+ check(hal_xdr_decode_buffer(&iptr, ilimit, previous_uuid->uuid, &uuid_len));
+ if (uuid_len != sizeof(previous_uuid->uuid))
+ return HAL_ERROR_KEY_NAME_TOO_LONG;
+ *result_len = array_len;
+ }
+ return rpc_ret;
+}
+
+static hal_error_t pkey_remote_set_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+ uint8_t outbuf[nargs(5) + pad(value_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
+ uint8_t inbuf[nargs(3)];
+ const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf);
+ hal_client_handle_t dummy_client = {0};
+ hal_error_t rpc_ret;
+
+ check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_SET_ATTRIBUTE));
+ check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
+ check(hal_xdr_encode_int(&optr, olimit, pkey.handle));
+ check(hal_xdr_encode_int(&optr, olimit, type));
+ check(hal_xdr_encode_buffer(&optr, olimit, value, value_len));
+ check(hal_rpc_send(outbuf, optr - outbuf));
+
+ check(read_matching_packet(RPC_FUNC_PKEY_SET_ATTRIBUTE, inbuf, sizeof(inbuf), &iptr, &ilimit));
+
+ check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
+ return rpc_ret;
+}
+
+static hal_error_t pkey_remote_get_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+ uint8_t outbuf[nargs(5)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
+ uint8_t inbuf[nargs(4) + pad(value_max)];
+ const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf);
+ uint32_t vlen32 = value_max;
+ hal_client_handle_t dummy_client = {0};
+ hal_error_t rpc_ret;
+
+ check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_ATTRIBUTE));
+ check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
+ check(hal_xdr_encode_int(&optr, olimit, pkey.handle));
+ check(hal_xdr_encode_int(&optr, olimit, type));
+ check(hal_xdr_encode_int(&optr, olimit, vlen32));
+ check(hal_rpc_send(outbuf, optr - outbuf));
+
+ check(read_matching_packet(RPC_FUNC_PKEY_GET_ATTRIBUTE, inbuf, sizeof(inbuf), &iptr, &ilimit));
+
+ check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
+ if (rpc_ret == HAL_OK) {
+ check(hal_xdr_decode_buffer(&iptr, ilimit, value, &vlen32));
+ *value_len = (size_t) vlen32;
+ }
+
+ return rpc_ret;
+}
+
+static hal_error_t pkey_remote_delete_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type)
+{
+ uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
+ uint8_t inbuf[nargs(3)];
+ const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf);
+ hal_client_handle_t dummy_client = {0};
+ hal_error_t rpc_ret;
+
+ check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_DELETE_ATTRIBUTE));
+ check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
+ check(hal_xdr_encode_int(&optr, olimit, pkey.handle));
+ check(hal_xdr_encode_int(&optr, olimit, type));
+ check(hal_rpc_send(outbuf, optr - outbuf));
+
+ check(read_matching_packet(RPC_FUNC_PKEY_DELETE_ATTRIBUTE, inbuf, sizeof(inbuf), &iptr, &ilimit));
+
+ check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
+ return rpc_ret;
+}
+
#if RPC_CLIENT == RPC_CLIENT_MIXED
/*
@@ -918,7 +1052,11 @@ const hal_rpc_pkey_dispatch_t hal_rpc_remote_pkey_dispatch = {
pkey_remote_get_public_key,
pkey_remote_sign,
pkey_remote_verify,
- pkey_remote_list
+ pkey_remote_list,
+ pkey_remote_match,
+ pkey_remote_set_attribute,
+ pkey_remote_get_attribute,
+ pkey_remote_delete_attribute
};
#if RPC_CLIENT == RPC_CLIENT_MIXED
@@ -935,7 +1073,11 @@ const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = {
pkey_remote_get_public_key,
pkey_mixed_sign,
pkey_mixed_verify,
- pkey_remote_list
+ pkey_remote_list,
+ pkey_remote_match,
+ pkey_remote_set_attribute,
+ pkey_remote_get_attribute,
+ pkey_remote_delete_attribute
};
#endif /* RPC_CLIENT == RPC_CLIENT_MIXED */
diff --git a/rpc_pkey.c b/rpc_pkey.c
index cf0975b..207d980 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -867,6 +867,94 @@ static hal_error_t pkey_local_list(hal_pkey_info_t *result,
return err;
}
+static hal_error_t pkey_local_match(const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ hal_rpc_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ hal_uuid_t *previous_uuid)
+{
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_match(ks, type, curve, flags, attributes, attributes_len,
+ result, result_len, result_max, previous_uuid)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
+
+static hal_error_t pkey_local_set_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len)
+{
+ hal_pkey_slot_t *slot = find_handle(pkey);
+
+ if (slot == NULL)
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_set_attribute(ks, slot, type, value, value_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
+
+static hal_error_t pkey_local_get_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type,
+ uint8_t *value,
+ size_t *value_len,
+ const size_t value_max)
+{
+ hal_pkey_slot_t *slot = find_handle(pkey);
+
+ if (slot == NULL)
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_get_attribute(ks, slot, type, value, value_len, value_max)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
+
+static hal_error_t pkey_local_delete_attribute(const hal_pkey_handle_t pkey,
+ const uint32_t type)
+{
+ hal_pkey_slot_t *slot = find_handle(pkey);
+
+ if (slot == NULL)
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_delete_attribute(ks, slot, type)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
+
const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = {
pkey_local_load,
pkey_local_find,
@@ -880,7 +968,11 @@ const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = {
pkey_local_get_public_key,
pkey_local_sign,
pkey_local_verify,
- pkey_local_list
+ pkey_local_list,
+ pkey_local_match,
+ pkey_local_set_attribute,
+ pkey_local_get_attribute,
+ pkey_local_delete_attribute
};
/*
diff --git a/rpc_server.c b/rpc_server.c
index 22e354a..5f3502f 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -560,8 +560,8 @@ static hal_error_t pkey_get_public_key(const uint8_t **iptr, const uint8_t * con
return ret;
}
-static hal_error_t pkey_remote_sign(const uint8_t **iptr, const uint8_t * const ilimit,
- uint8_t **optr, const uint8_t * const olimit)
+static hal_error_t pkey_sign(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
{
hal_client_handle_t client __attribute__((unused));
hal_session_handle_t session;
@@ -596,8 +596,8 @@ static hal_error_t pkey_remote_sign(const uint8_t **iptr, const uint8_t * const
return ret;
}
-static hal_error_t pkey_remote_verify(const uint8_t **iptr, const uint8_t * const ilimit,
- uint8_t **optr, const uint8_t * const olimit)
+static hal_error_t pkey_verify(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
{
hal_client_handle_t client __attribute__((unused));
hal_session_handle_t session;
@@ -655,9 +655,8 @@ static hal_error_t pkey_list(const uint8_t **iptr, const uint8_t * const ilimit,
ret = hal_rpc_local_pkey_dispatch.list(result, &result_len, result_max, flags);
if (ret == HAL_OK) {
- int i;
check(hal_xdr_encode_int(optr, olimit, result_len));
- for (i = 0; i < result_len; ++i) {
+ for (int i = 0; i < result_len; ++i) {
if ((ret = hal_xdr_encode_pkey_info(optr, olimit, &result[i])) != HAL_OK) {
*optr = optr_orig;
break;
@@ -668,6 +667,132 @@ static hal_error_t pkey_list(const uint8_t **iptr, const uint8_t * const ilimit,
return ret;
}
+#warning Which RPC pkey functions take session looks kind of messed up
+// list() and match() probably should take session, sign() and verify() probably should not
+
+static hal_error_t pkey_match(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ uint32_t type, curve, attributes_len, result_max, previous_uuid_len;
+ const uint8_t *previous_uuid_ptr;
+ hal_key_flags_t flags;
+ hal_error_t ret;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &type));
+ check(hal_xdr_decode_int(iptr, ilimit, &curve));
+ check(hal_xdr_decode_int(iptr, ilimit, &flags));
+ check(hal_xdr_decode_int(iptr, ilimit, &attributes_len));
+
+ hal_rpc_pkey_attribute_t attributes[attributes_len > 0 ? attributes_len : 1];
+
+ for (int i = 0; i < attributes_len; i++) {
+ hal_rpc_pkey_attribute_t *a = &attributes[i];
+ uint32_t value_len;
+ check(hal_xdr_decode_int(iptr, ilimit, &a->type));
+ check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &a->value, &value_len));
+ a->length = value_len;
+ }
+
+ check(hal_xdr_decode_int(iptr, ilimit, &result_max));
+ check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &previous_uuid_ptr, &previous_uuid_len));
+
+ if (previous_uuid_len != sizeof(hal_uuid_t))
+ return HAL_ERROR_KEY_NAME_TOO_LONG;
+
+ hal_uuid_t result[result_max];
+ unsigned result_len;
+
+ ret = hal_rpc_local_pkey_dispatch.match(type, curve, flags, attributes, attributes_len,
+ result, &result_len, result_max,
+ (hal_uuid_t *) previous_uuid_ptr);
+
+ if (ret == HAL_OK) {
+ uint8_t *optr_orig = *optr;
+ check(hal_xdr_encode_int(optr, olimit, result_len));
+ for (int i = 0; i < result_len; ++i) {
+ if ((ret = hal_xdr_encode_buffer(optr, olimit, result[i].uuid,
+ sizeof(result[i].uuid))) != HAL_OK) {
+ *optr = optr_orig;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static hal_error_t pkey_set_attribute(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ hal_pkey_handle_t pkey;
+ uint32_t type;
+ const uint8_t *value;
+ uint32_t value_len;
+ hal_error_t ret;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &type));
+ check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &value, &value_len));
+
+ ret = hal_rpc_local_pkey_dispatch.set_attribute(pkey, type, value, value_len);
+
+ return ret;
+}
+
+static hal_error_t pkey_get_attribute(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ hal_pkey_handle_t pkey;
+ uint32_t type;
+ size_t value_len;
+ uint32_t value_max;
+ uint8_t *optr_orig = *optr;
+ hal_error_t ret;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &type));
+ check(hal_xdr_decode_int(iptr, ilimit, &value_max));
+ if (value_max > olimit - *optr - 4)
+ return HAL_ERROR_RPC_PACKET_OVERFLOW;
+
+ *optr += 4;
+ ret = hal_rpc_local_pkey_dispatch.get_attribute(pkey, type, *optr, &value_len, value_max);
+
+ if (ret == HAL_OK) {
+ *optr = optr_orig;
+ check(hal_xdr_encode_int(optr, olimit, value_len));
+ *optr += pad(value_len);
+ }
+ else {
+ *optr = optr_orig;
+ }
+
+ return ret;
+}
+
+static hal_error_t pkey_delete_attribute(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ hal_pkey_handle_t pkey;
+ uint32_t type;
+ hal_error_t ret;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &type));
+
+ ret = hal_rpc_local_pkey_dispatch.delete_attribute(pkey, type);
+
+ return ret;
+}
+
hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen,
uint8_t * const obuf, size_t * const olen)
{
@@ -753,14 +878,26 @@ hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ile
ret = pkey_get_public_key(&iptr, ilimit, &optr, olimit);
break;
case RPC_FUNC_PKEY_SIGN:
- ret = pkey_remote_sign(&iptr, ilimit, &optr, olimit);
+ ret = pkey_sign(&iptr, ilimit, &optr, olimit);
break;
case RPC_FUNC_PKEY_VERIFY:
- ret = pkey_remote_verify(&iptr, ilimit, &optr, olimit);
+ ret = pkey_verify(&iptr, ilimit, &optr, olimit);
break;
case RPC_FUNC_PKEY_LIST:
ret = pkey_list(&iptr, ilimit, &optr, olimit);
break;
+ case RPC_FUNC_PKEY_MATCH:
+ ret = pkey_match(&iptr, ilimit, &optr, olimit);
+ break;
+ case RPC_FUNC_PKEY_SET_ATTRIBUTE:
+ ret = pkey_set_attribute(&iptr, ilimit, &optr, olimit);
+ break;
+ case RPC_FUNC_PKEY_GET_ATTRIBUTE:
+ ret = pkey_get_attribute(&iptr, ilimit, &optr, olimit);
+ break;
+ case RPC_FUNC_PKEY_DELETE_ATTRIBUTE:
+ ret = pkey_delete_attribute(&iptr, ilimit, &optr, olimit);
+ break;
default:
ret = HAL_ERROR_RPC_BAD_FUNCTION;
break;