From cef7ba6f7024a2c3a53760be8c5fc4f937e8efb5 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Thu, 25 Feb 2016 17:27:33 -0500 Subject: RPC over loopback socket, just to work out the mechanics for serialization and dispatch. --- rpc_client.c | 525 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 495 insertions(+), 30 deletions(-) (limited to 'rpc_client.c') diff --git a/rpc_client.c b/rpc_client.c index 3d4fcee..d58cb92 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -3,8 +3,8 @@ * ------------ * Remote procedure call client-side private API implementation. * - * Authors: Rob Austein - * Copyright (c) 2015, NORDUnet A/S All rights reserved. + * Authors: Rob Austein, Paul Selkirk + * Copyright (c) 2015-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 @@ -33,25 +33,60 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "hal.h" #include "hal_internal.h" /* - * RPC calls. Not implemented yet. + * RPC calls. */ -#warning These are all placeholders, waiting to be filled in with the real RPC calls +#define check(op) if ((ret = (op)) != HAL_OK) return ret; + +#define pad(n) (((n) + 3) & ~3) static hal_error_t get_random(void *buffer, const size_t length) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(length)], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t rcvlen = length; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_GET_RANDOM)); + check(rpc_encode_int(&optr, olimit, (uint32_t)length)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_buffer(&iptr, ilimit, buffer, &rcvlen)); + // XXX check rcvlen vs length + } + return rpc_ret; } static hal_error_t set_pin(const hal_client_handle_t client, const hal_user_t user, - const char * const newpin, const size_t newpin_len) + const char * const pin, const size_t pin_len) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12 + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_SET_PIN)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, user)); + check(rpc_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } /* @@ -72,39 +107,141 @@ static hal_error_t login(const hal_client_handle_t client, const hal_user_t user, const char * const pin, const size_t pin_len) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12 + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGIN)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, user)); + check(rpc_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t logout(const hal_client_handle_t client) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGOUT)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t logout_all(void) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[4], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGOUT_ALL)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t is_logged_in(const hal_client_handle_t client, const hal_user_t user) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_IS_LOGGED_IN)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, user)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t *length) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t len32; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); + check(rpc_encode_int(&optr, olimit, alg)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &len32)); + *length = (size_t)len32; + } + return rpc_ret; } static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg, uint8_t *id, size_t *len, const size_t len_max) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(len_max)], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t len32 = len_max; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); + check(rpc_encode_int(&optr, olimit, alg)); + check(rpc_encode_int(&optr, olimit, len_max)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_buffer(&iptr, ilimit, id, &len32)); + *len = len32; + } + return rpc_ret; } static hal_error_t hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_algorithm_t *alg) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t alg32; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_ALGORITHM)); + check(rpc_encode_int(&optr, olimit, hash.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &alg32)); + *alg = (hal_digest_algorithm_t)alg32; + } + return rpc_ret; } static hal_error_t hash_initialize(const hal_client_handle_t client, @@ -113,19 +250,68 @@ static hal_error_t hash_initialize(const hal_client_handle_t client, const hal_digest_algorithm_t alg, const uint8_t * const key, const size_t key_len) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[20 + pad(key_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_INITIALIZE)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_int(&optr, olimit, alg)); + check(rpc_encode_buffer(&optr, olimit, key, key_len)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &hash->handle)); + } + return rpc_ret; } static hal_error_t hash_update(const hal_hash_handle_t hash, const uint8_t * data, const size_t length) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12 + pad(length)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_UPDATE)); + check(rpc_encode_int(&optr, olimit, hash.handle)); + check(rpc_encode_buffer(&optr, olimit, data, length)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t hash_finalize(const hal_hash_handle_t hash, uint8_t *digest, const size_t length) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(length)], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t digest_len = length; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_FINALIZE)); + check(rpc_encode_int(&optr, olimit, hash.handle)); + check(rpc_encode_int(&optr, olimit, length)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_buffer(&iptr, ilimit, digest, &digest_len)); + /* XXX check digest_len vs length */ + } + return rpc_ret; } static hal_error_t pkey_load(const hal_client_handle_t client, @@ -137,7 +323,28 @@ static hal_error_t pkey_load(const hal_client_handle_t client, const uint8_t * const der, const size_t der_len, const hal_key_flags_t flags) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[32 + pad(name_len) + pad(der_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_LOAD)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_int(&optr, olimit, type)); + check(rpc_encode_int(&optr, olimit, curve)); + check(rpc_encode_buffer(&optr, olimit, name, name_len)); + check(rpc_encode_buffer(&optr, olimit, der, der_len)); + check(rpc_encode_int(&optr, olimit, flags)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) + check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + + return rpc_ret; } static hal_error_t pkey_find(const hal_client_handle_t client, @@ -146,7 +353,25 @@ static hal_error_t pkey_find(const hal_client_handle_t client, const hal_key_type_t type, const uint8_t * const name, const size_t name_len) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[20 + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_FIND)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_int(&optr, olimit, type)); + check(rpc_encode_buffer(&optr, olimit, name, name_len)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) + check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + + return rpc_ret; } static hal_error_t pkey_generate_rsa(const hal_client_handle_t client, @@ -157,7 +382,27 @@ static hal_error_t pkey_generate_rsa(const hal_client_handle_t client, const uint8_t * const exp, const size_t exp_len, const hal_key_flags_t flags) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[28 + pad(name_len) + pad(exp_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_RSA)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_buffer(&optr, olimit, name, name_len)); + check(rpc_encode_int(&optr, olimit, key_len)); + check(rpc_encode_buffer(&optr, olimit, exp, exp_len)); + check(rpc_encode_int(&optr, olimit, flags)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) + check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + + return rpc_ret; } static hal_error_t pkey_generate_ec(const hal_client_handle_t client, @@ -167,40 +412,153 @@ static hal_error_t pkey_generate_ec(const hal_client_handle_t client, const hal_curve_name_t curve, const hal_key_flags_t flags) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[24 + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_EC)); + check(rpc_encode_int(&optr, olimit, client.handle)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_buffer(&optr, olimit, name, name_len)); + check(rpc_encode_int(&optr, olimit, curve)); + check(rpc_encode_int(&optr, olimit, flags)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) + check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + + return rpc_ret; } static hal_error_t pkey_close(const hal_pkey_handle_t pkey) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_CLOSE)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t pkey_delete(const hal_pkey_handle_t pkey) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_DELETE)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; } static hal_error_t pkey_get_key_type(const hal_pkey_handle_t pkey, hal_key_type_t *type) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t type32; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_TYPE)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &type32)); + *type = (hal_key_type_t)type32; + } + return rpc_ret; } static hal_error_t pkey_get_key_flags(const hal_pkey_handle_t pkey, hal_key_flags_t *flags) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t flags32; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_FLAGS)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &flags32)); + *flags = (hal_key_flags_t)flags32; + } + return rpc_ret; } static size_t pkey_get_public_key_len(const hal_pkey_handle_t pkey) { - return 0; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t len32; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_int(&iptr, ilimit, &len32)); + return (size_t)len32; + } + else + return 0; } static hal_error_t pkey_get_public_key(const hal_pkey_handle_t pkey, uint8_t *der, size_t *der_len, const size_t der_max) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[12], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(der_max)], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t dlen32 = der_max; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_encode_int(&optr, olimit, der_max)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_buffer(&iptr, ilimit, der, &dlen32)); + *der_len = (size_t)dlen32; + } + return rpc_ret; } static hal_error_t pkey_remote_sign(const hal_session_handle_t session, @@ -209,7 +567,28 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session, const uint8_t * const input, const size_t input_len, uint8_t * signature, size_t *signature_len, const size_t signature_max) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[24 + pad(input_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(signature_max)], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t slen32 = signature_max; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_SIGN)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_encode_int(&optr, olimit, hash.handle)); + check(rpc_encode_buffer(&optr, olimit, input, input_len)); + check(rpc_encode_int(&optr, olimit, signature_max)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(rpc_decode_buffer(&iptr, ilimit, signature, &slen32)); + *signature_len = (size_t)slen32; + } + return rpc_ret; } static hal_error_t pkey_remote_verify(const hal_session_handle_t session, @@ -218,14 +597,66 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session, const uint8_t * const input, const size_t input_len, const uint8_t * const signature, const size_t signature_len) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[24 + pad(input_len) + pad(signature_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[4], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_VERIFY)); + check(rpc_encode_int(&optr, olimit, session.handle)); + check(rpc_encode_int(&optr, olimit, pkey.handle)); + check(rpc_encode_int(&optr, olimit, hash.handle)); + check(rpc_encode_buffer(&optr, olimit, input, input_len)); + check(rpc_encode_buffer(&optr, olimit, signature, signature_len)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + return rpc_ret; +} + +static hal_error_t rpc_decode_pkey_info(uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_info_t *info) +{ + uint32_t i32; + hal_error_t ret; + + check(rpc_decode_int(iptr, ilimit, &i32)); info->type = i32; + check(rpc_decode_int(iptr, ilimit, &i32)); info->curve = i32; + check(rpc_decode_int(iptr, ilimit, &i32)); info->flags = i32; + check(rpc_decode_buffer(iptr, ilimit, (uint8_t *)&info->name[0], &i32)); info->name_len = i32; + return HAL_OK; } static hal_error_t pkey_list(hal_pkey_info_t *result, unsigned *result_len, const unsigned result_max) { - return HAL_ERROR_IMPOSSIBLE; + uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8 + pad(result_max * sizeof(hal_pkey_info_t))], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + uint32_t len; + hal_error_t ret, rpc_ret; + + check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_LIST)); + check(rpc_encode_int(&optr, olimit, result_max)); + check(rpc_send(outbuf, optr - outbuf)); + + check(rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + int i; + check(rpc_decode_int(&iptr, ilimit, &len)); + *result_len = len; + for (i = 0; i < len; ++i) { + if ((ret = rpc_decode_pkey_info(&iptr, ilimit, &result[i])) != HAL_OK) { + *result_len = 0; + return ret; + } + } + } + return rpc_ret; } @@ -317,6 +748,40 @@ const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = { pkey_list }; +const hal_rpc_misc_dispatch_t * hal_rpc_misc_dispatch; +const hal_rpc_hash_dispatch_t * hal_rpc_hash_dispatch; +const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch; + +hal_error_t rpc_client_init(rpc_locality_t locality) +{ + switch (locality) { + case RPC_LOCAL: + hal_rpc_misc_dispatch = &hal_rpc_local_misc_dispatch; + hal_rpc_hash_dispatch = &hal_rpc_local_hash_dispatch; + hal_rpc_pkey_dispatch = &hal_rpc_local_pkey_dispatch; + break; + case RPC_REMOTE: + hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch; + hal_rpc_hash_dispatch = &hal_rpc_remote_hash_dispatch; + hal_rpc_pkey_dispatch = &hal_rpc_remote_pkey_dispatch; + break; + case RPC_MIXED: + hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch; + hal_rpc_hash_dispatch = &hal_rpc_remote_hash_dispatch; + hal_rpc_pkey_dispatch = &hal_rpc_mixed_pkey_dispatch; + break; + default: + return HAL_ERROR_BAD_ARGUMENTS; + } + return rpc_client_transport_init(); +} + +hal_error_t rpc_client_close(void) +{ + return rpc_client_transport_close(); +} + + /* * Local variables: * indent-tabs-mode: nil -- cgit v1.2.3