diff options
Diffstat (limited to 'p11-kit/rpc-client.c')
-rw-r--r-- | p11-kit/rpc-client.c | 2104 |
1 files changed, 0 insertions, 2104 deletions
diff --git a/p11-kit/rpc-client.c b/p11-kit/rpc-client.c deleted file mode 100644 index c69dcfd..0000000 --- a/p11-kit/rpc-client.c +++ /dev/null @@ -1,2104 +0,0 @@ -/* - * Copyright (C) 2008 Stefan Walter - * Copyright (C) 2012 Red Hat Inc. - * - * 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. - * * The names of contributors to this software may not 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 OWNER 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. - * - * Author: Stef Walter <stefw@gnome.org> - */ - -#include "config.h" - -#define P11_DEBUG_FLAG P11_DEBUG_RPC -#include "debug.h" -#include "pkcs11.h" -#include "pkcs11x.h" -#include "library.h" -#include "message.h" -#include "private.h" -#include "rpc.h" -#include "rpc-message.h" -#include "virtual.h" - -#include <assert.h> -#include <string.h> -#include <unistd.h> - -/* The error used by us when parsing of rpc message fails */ -#define PARSE_ERROR CKR_DEVICE_ERROR - -typedef struct { - p11_mutex_t mutex; - p11_rpc_client_vtable *vtable; - unsigned int initialized_forkid; - bool initialize_done; -} rpc_client; - -/* Allocator for call session buffers */ -static void * -log_allocator (void *pointer, - size_t size) -{ - void *result = realloc (pointer, (size_t)size); - return_val_if_fail (!size || result != NULL, NULL); - return result; -} - -static CK_RV -call_prepare (rpc_client *module, - p11_rpc_message *msg, - int call_id) -{ - p11_buffer *buffer; - - assert (module != NULL); - assert (msg != NULL); - - if (module->initialized_forkid != p11_forkid) - return CKR_CRYPTOKI_NOT_INITIALIZED; - if (!module->initialize_done) - return CKR_DEVICE_REMOVED; - - buffer = p11_rpc_buffer_new_full (64, log_allocator, free); - return_val_if_fail (buffer != NULL, CKR_GENERAL_ERROR); - - /* We use the same buffer for reading and writing */ - p11_rpc_message_init (msg, buffer, buffer); - - /* Put in the Call ID and signature */ - if (!p11_rpc_message_prep (msg, call_id, P11_RPC_REQUEST)) - return_val_if_reached (CKR_HOST_MEMORY); - - p11_debug ("prepared call: %d", call_id); - return CKR_OK; -} - -static CK_RV -call_run (rpc_client *module, - p11_rpc_message *msg) -{ - CK_RV ret = CKR_OK; - CK_ULONG ckerr; - - int call_id; - - assert (module != NULL); - assert (msg != NULL); - - /* Did building the call fail? */ - if (p11_buffer_failed (msg->output)) - return_val_if_reached (CKR_HOST_MEMORY); - - /* Make sure that the signature is valid */ - assert (p11_rpc_message_is_verified (msg)); - call_id = msg->call_id; - - /* Do the transport send and receive */ - assert (module->vtable->transport != NULL); - ret = (module->vtable->transport) (module->vtable, - msg->output, - msg->input); - - if (ret != CKR_OK) - return ret; - - if (!p11_rpc_message_parse (msg, P11_RPC_RESPONSE)) - return CKR_DEVICE_ERROR; - - /* If it's an error code then return it */ - if (msg->call_id == P11_RPC_CALL_ERROR) { - if (!p11_rpc_message_read_ulong (msg, &ckerr)) { - p11_message ("invalid rpc error response: too short"); - return CKR_DEVICE_ERROR; - } - - if (ckerr <= CKR_OK) { - p11_message ("invalid rpc error response: bad error code"); - return CKR_DEVICE_ERROR; - } - - /* An error code from the other side */ - return (CK_RV)ckerr; - } - - /* Make sure other side answered the right call */ - if (call_id != msg->call_id) { - p11_message ("invalid rpc response: call mismatch"); - return CKR_DEVICE_ERROR; - } - - assert (!p11_buffer_failed (msg->input)); - - p11_debug ("parsing response values"); - return CKR_OK; -} - -static CK_RV -call_done (rpc_client *module, - p11_rpc_message *msg, - CK_RV ret) -{ - assert (module != NULL); - assert (msg != NULL); - - /* Check for parsing errors that were not caught elsewhere */ - if (ret == CKR_OK) { - if (p11_buffer_failed (msg->input)) { - p11_message ("invalid rpc response: bad argument data"); - ret = CKR_GENERAL_ERROR; - } else { - /* Double check that the signature matched our decoding */ - assert (p11_rpc_message_is_verified (msg)); - } - } - - /* We used the same buffer for input/output, so this frees both */ - assert (msg->input == msg->output); - p11_rpc_buffer_free (msg->input); - - p11_rpc_message_clear (msg); - - return ret; -} - -/* ----------------------------------------------------------------------------- - * MODULE SPECIFIC PROTOCOL CODE - */ - -static CK_RV -proto_read_attribute_array (p11_rpc_message *msg, - CK_ATTRIBUTE_PTR arr, - CK_ULONG len) -{ - uint32_t i, num, value, type; - CK_ATTRIBUTE_PTR attr; - const unsigned char *attrval = NULL; - size_t attrlen = 0; - unsigned char validity; - CK_RV ret; - - assert (len != 0); - assert (msg != NULL); - assert (msg->input != NULL); - - /* Make sure this is in the right order */ - assert (!msg->signature || p11_rpc_message_verify_part (msg, "aA")); - - /* Get the number of items. We need this value to be correct */ - if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &num)) - return PARSE_ERROR; - - /* - * This should never happen in normal operation. It denotes a goof up - * on the other side of our RPC. We should be indicating the exact number - * of attributes to the other side. And it should respond with the same - * number. - */ - if (len != num) { - p11_message ("received an attribute array with wrong number of attributes"); - return PARSE_ERROR; - } - - ret = CKR_OK; - - /* We need to go ahead and read everything in all cases */ - for (i = 0; i < num; ++i) { - - /* The attribute type */ - p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &type); - - /* Attribute validity */ - p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &validity); - - /* And the data itself */ - if (validity) { - if (p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &value) && - p11_rpc_buffer_get_byte_array (msg->input, &msg->parsed, &attrval, &attrlen)) { - if (attrval && value != attrlen) { - p11_message ("attribute length does not match attribute data"); - return PARSE_ERROR; - } - attrlen = value; - } - } - - /* Don't act on this data unless no errors */ - if (p11_buffer_failed (msg->input)) - break; - - /* Try and stuff it in the output data */ - if (arr) { - attr = &(arr[i]); - if (attr->type != type) { - p11_message ("returned attributes in invalid order"); - return PARSE_ERROR; - } - - if (validity) { - /* Just requesting the attribute size */ - if (!attr->pValue) { - attr->ulValueLen = attrlen; - - /* Wants attribute data, but too small */ - } else if (attr->ulValueLen < attrlen) { - attr->ulValueLen = attrlen; - ret = CKR_BUFFER_TOO_SMALL; - - /* Wants attribute data, value is null */ - } else if (attrval == NULL) { - attr->ulValueLen = 0; - - /* Wants attribute data, enough space */ - } else { - attr->ulValueLen = attrlen; - memcpy (attr->pValue, attrval, attrlen); - } - - /* Not a valid attribute */ - } else { - attr->ulValueLen = ((CK_ULONG)-1); - } - } - } - - if (p11_buffer_failed (msg->input)) - return PARSE_ERROR; - - /* Read in the code that goes along with these attributes */ - if (!p11_rpc_message_read_ulong (msg, &ret)) - return PARSE_ERROR; - - return ret; -} - -static CK_RV -proto_read_byte_array (p11_rpc_message *msg, - CK_BYTE_PTR arr, - CK_ULONG_PTR len, - CK_ULONG max) -{ - const unsigned char *val; - unsigned char valid; - uint32_t length; - size_t vlen; - - assert (len != NULL); - assert (msg != NULL); - assert (msg->input != NULL); - - /* Make sure this is in the right order */ - assert (!msg->signature || p11_rpc_message_verify_part (msg, "ay")); - - /* A single byte which determines whether valid or not */ - if (!p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &valid)) - return PARSE_ERROR; - - /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */ - if (!valid) { - if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &length)) - return PARSE_ERROR; - - *len = length; - - if (arr) - return CKR_BUFFER_TOO_SMALL; - else - return CKR_OK; - } - - /* Get the actual bytes */ - if (!p11_rpc_buffer_get_byte_array (msg->input, &msg->parsed, &val, &vlen)) - return PARSE_ERROR; - - *len = vlen; - - /* Just asking us for size */ - if (!arr) - return CKR_OK; - - if (max < vlen) - return CKR_BUFFER_TOO_SMALL; - - /* Enough space, yay */ - memcpy (arr, val, vlen); - return CKR_OK; -} - -static CK_RV -proto_read_ulong_array (p11_rpc_message *msg, CK_ULONG_PTR arr, - CK_ULONG_PTR len, CK_ULONG max) -{ - uint32_t i, num; - uint64_t val; - unsigned char valid; - - assert (len != NULL); - assert (msg != NULL); - assert (msg->input != NULL); - - /* Make sure this is in the right order */ - assert (!msg->signature || p11_rpc_message_verify_part (msg, "au")); - - /* A single byte which determines whether valid or not */ - if (!p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &valid)) - return PARSE_ERROR; - - /* Get the number of items. */ - if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &num)) - return PARSE_ERROR; - - *len = num; - - /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */ - if (!valid) { - if (arr) - return CKR_BUFFER_TOO_SMALL; - else - return CKR_OK; - } - - if (max < num) - return CKR_BUFFER_TOO_SMALL; - - /* We need to go ahead and read everything in all cases */ - for (i = 0; i < num; ++i) { - p11_rpc_buffer_get_uint64 (msg->input, &msg->parsed, &val); - if (arr) - arr[i] = (CK_ULONG)val; - } - - return p11_buffer_failed (msg->input) ? PARSE_ERROR : CKR_OK; -} - -/* Used to override the supported mechanisms in tests */ -CK_MECHANISM_TYPE *p11_rpc_mechanisms_override_supported = NULL; - -static bool -mechanism_has_sane_parameters (CK_MECHANISM_TYPE type) -{ - int i; - - /* This can be set from tests, to override default set of supported */ - if (p11_rpc_mechanisms_override_supported) { - for (i = 0; p11_rpc_mechanisms_override_supported[i] != 0; i++) { - if (p11_rpc_mechanisms_override_supported[i] == type) - return true; - } - - return false; - } - - /* This list is incomplete */ - switch (type) { - case CKM_RSA_PKCS_OAEP: - case CKM_RSA_PKCS_PSS: - return true; - default: - return false; - } -} - -static bool -mechanism_has_no_parameters (CK_MECHANISM_TYPE mech) -{ - /* This list is incomplete */ - - switch (mech) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - case CKM_RSA_X9_31_KEY_PAIR_GEN: - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - case CKM_RSA_X9_31: - case CKM_MD2_RSA_PKCS: - case CKM_MD5_RSA_PKCS: - case CKM_SHA1_RSA_PKCS: - case CKM_SHA256_RSA_PKCS: - case CKM_SHA384_RSA_PKCS: - case CKM_SHA512_RSA_PKCS: - case CKM_RIPEMD128_RSA_PKCS: - case CKM_RIPEMD160_RSA_PKCS: - case CKM_SHA1_RSA_X9_31: - case CKM_DSA_KEY_PAIR_GEN: - case CKM_DSA_PARAMETER_GEN: - case CKM_DSA: - case CKM_DSA_SHA1: - case CKM_FORTEZZA_TIMESTAMP: - case CKM_EC_KEY_PAIR_GEN: - case CKM_ECDSA: - case CKM_ECDSA_SHA1: - case CKM_DH_PKCS_KEY_PAIR_GEN: - case CKM_DH_PKCS_PARAMETER_GEN: - case CKM_X9_42_DH_KEY_PAIR_GEN: - case CKM_X9_42_DH_PARAMETER_GEN: - case CKM_KEA_KEY_PAIR_GEN: - case CKM_GENERIC_SECRET_KEY_GEN: - case CKM_RC2_KEY_GEN: - case CKM_RC4_KEY_GEN: - case CKM_RC4: - case CKM_RC5_KEY_GEN: - case CKM_AES_KEY_GEN: - case CKM_AES_ECB: - case CKM_AES_MAC: - case CKM_DES_KEY_GEN: - case CKM_DES2_KEY_GEN: - case CKM_DES3_KEY_GEN: - case CKM_CDMF_KEY_GEN: - case CKM_CAST_KEY_GEN: - case CKM_CAST3_KEY_GEN: - case CKM_CAST128_KEY_GEN: - case CKM_IDEA_KEY_GEN: - case CKM_SSL3_PRE_MASTER_KEY_GEN: - case CKM_TLS_PRE_MASTER_KEY_GEN: - case CKM_SKIPJACK_KEY_GEN: - case CKM_BATON_KEY_GEN: - case CKM_JUNIPER_KEY_GEN: - case CKM_RC2_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST128_ECB: - case CKM_RC5_ECB: - case CKM_IDEA_ECB: - case CKM_RC2_MAC: - case CKM_DES_MAC: - case CKM_DES3_MAC: - case CKM_CDMF_MAC: - case CKM_CAST_MAC: - case CKM_CAST3_MAC: - case CKM_RC5_MAC: - case CKM_IDEA_MAC: - case CKM_SSL3_MD5_MAC: - case CKM_SSL3_SHA1_MAC: - case CKM_SKIPJACK_WRAP: - case CKM_BATON_WRAP: - case CKM_JUNIPER_WRAP: - case CKM_MD2: - case CKM_MD2_HMAC: - case CKM_MD5: - case CKM_MD5_HMAC: - case CKM_SHA_1: - case CKM_SHA_1_HMAC: - case CKM_SHA256: - case CKM_SHA256_HMAC: - case CKM_SHA384: - case CKM_SHA384_HMAC: - case CKM_SHA512: - case CKM_SHA512_HMAC: - case CKM_FASTHASH: - case CKM_RIPEMD128: - case CKM_RIPEMD128_HMAC: - case CKM_RIPEMD160: - case CKM_RIPEMD160_HMAC: - case CKM_KEY_WRAP_LYNKS: - return true; - default: - return false; - }; -} - -static bool -mechanism_is_supported (CK_MECHANISM_TYPE mech) -{ - if (mechanism_has_no_parameters (mech) || - mechanism_has_sane_parameters (mech)) - return true; - return false; -} -static void -mechanism_list_purge (CK_MECHANISM_TYPE_PTR mechs, - CK_ULONG *n_mechs) -{ - int i; - - assert (mechs != NULL); - assert (n_mechs != NULL); - - for (i = 0; i < (int)(*n_mechs); ++i) { - if (!mechanism_is_supported (mechs[i])) { - - /* Remove the mechanism from the list */ - memmove (&mechs[i], &mechs[i + 1], - (*n_mechs - i) * sizeof (CK_MECHANISM_TYPE)); - - --(*n_mechs); - --i; - } - } -} - -static CK_RV -proto_write_mechanism (p11_rpc_message *msg, - CK_MECHANISM_PTR mech) -{ - assert (msg != NULL); - assert (mech != NULL); - assert (msg->output != NULL); - - /* Make sure this is in the right order */ - assert (!msg->signature || p11_rpc_message_verify_part (msg, "M")); - - /* The mechanism type */ - p11_rpc_buffer_add_uint32 (msg->output, mech->mechanism); - - /* - * PKCS#11 mechanism parameters are not easy to serialize. They're - * completely different for so many mechanisms, they contain - * pointers to arbitrary memory, and many callers don't initialize - * them completely or properly. - * - * We only support certain mechanisms. - * - * Also callers do yucky things like leaving parts of the structure - * pointing to garbage if they don't think it's going to be used. - */ - - if (mechanism_has_no_parameters (mech->mechanism)) - p11_rpc_buffer_add_byte_array (msg->output, NULL, 0); - else if (mechanism_has_sane_parameters (mech->mechanism)) - p11_rpc_buffer_add_byte_array (msg->output, mech->pParameter, - mech->ulParameterLen); - else - return CKR_MECHANISM_INVALID; - - return p11_buffer_failed (msg->output) ? CKR_HOST_MEMORY : CKR_OK; -} - -static CK_RV -proto_read_info (p11_rpc_message *msg, - CK_INFO_PTR info) -{ - assert (msg != NULL); - assert (info != NULL); - - if (!p11_rpc_message_read_version (msg, &info->cryptokiVersion) || - !p11_rpc_message_read_space_string (msg, info->manufacturerID, 32) || - !p11_rpc_message_read_ulong (msg, &info->flags) || - !p11_rpc_message_read_space_string (msg, info->libraryDescription, 32) || - !p11_rpc_message_read_version (msg, &info->libraryVersion)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_slot_info (p11_rpc_message *msg, - CK_SLOT_INFO_PTR info) -{ - assert (msg != NULL); - assert (info != NULL); - - if (!p11_rpc_message_read_space_string (msg, info->slotDescription, 64) || - !p11_rpc_message_read_space_string (msg, info->manufacturerID, 32) || - !p11_rpc_message_read_ulong (msg, &info->flags) || - !p11_rpc_message_read_version (msg, &info->hardwareVersion) || - !p11_rpc_message_read_version (msg, &info->firmwareVersion)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_token_info (p11_rpc_message *msg, - CK_TOKEN_INFO_PTR info) -{ - assert (msg != NULL); - assert (info != NULL); - - if (!p11_rpc_message_read_space_string (msg, info->label, 32) || - !p11_rpc_message_read_space_string (msg, info->manufacturerID, 32) || - !p11_rpc_message_read_space_string (msg, info->model, 16) || - !p11_rpc_message_read_space_string (msg, info->serialNumber, 16) || - !p11_rpc_message_read_ulong (msg, &info->flags) || - !p11_rpc_message_read_ulong (msg, &info->ulMaxSessionCount) || - !p11_rpc_message_read_ulong (msg, &info->ulSessionCount) || - !p11_rpc_message_read_ulong (msg, &info->ulMaxRwSessionCount) || - !p11_rpc_message_read_ulong (msg, &info->ulRwSessionCount) || - !p11_rpc_message_read_ulong (msg, &info->ulMaxPinLen) || - !p11_rpc_message_read_ulong (msg, &info->ulMinPinLen) || - !p11_rpc_message_read_ulong (msg, &info->ulTotalPublicMemory) || - !p11_rpc_message_read_ulong (msg, &info->ulFreePublicMemory) || - !p11_rpc_message_read_ulong (msg, &info->ulTotalPrivateMemory) || - !p11_rpc_message_read_ulong (msg, &info->ulFreePrivateMemory) || - !p11_rpc_message_read_version (msg, &info->hardwareVersion) || - !p11_rpc_message_read_version (msg, &info->firmwareVersion) || - !p11_rpc_message_read_space_string (msg, info->utcTime, 16)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_mechanism_info (p11_rpc_message *msg, - CK_MECHANISM_INFO_PTR info) -{ - assert (msg != NULL); - assert (info != NULL); - - if (!p11_rpc_message_read_ulong (msg, &info->ulMinKeySize) || - !p11_rpc_message_read_ulong (msg, &info->ulMaxKeySize) || - !p11_rpc_message_read_ulong (msg, &info->flags)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_sesssion_info (p11_rpc_message *msg, - CK_SESSION_INFO_PTR info) -{ - assert (msg != NULL); - assert (info != NULL); - - if (!p11_rpc_message_read_ulong (msg, &info->slotID) || - !p11_rpc_message_read_ulong (msg, &info->state) || - !p11_rpc_message_read_ulong (msg, &info->flags) || - !p11_rpc_message_read_ulong (msg, &info->ulDeviceError)) - return PARSE_ERROR; - - return CKR_OK; -} - -/* ------------------------------------------------------------------- - * CALL MACROS - */ - -#define BEGIN_CALL_OR(call_id, self, if_no_daemon) \ - p11_debug (#call_id ": enter"); \ - { \ - rpc_client *_mod = ((p11_virtual *)self)->lower_module; p11_rpc_message _msg; \ - CK_RV _ret = call_prepare (_mod, &_msg, P11_RPC_CALL_##call_id); \ - if (_ret == CKR_DEVICE_REMOVED) return (if_no_daemon); \ - if (_ret != CKR_OK) return _ret; - -#define PROCESS_CALL \ - _ret = call_run (_mod, &_msg); \ - if (_ret != CKR_OK) goto _cleanup; - -#define RETURN(ret) \ - _ret = ret; \ - goto _cleanup; - -#define END_CALL \ - _cleanup: \ - _ret = call_done (_mod, &_msg, _ret); \ - p11_debug ("ret: %lu", _ret); \ - return _ret; \ - } - -#define IN_BYTE(val) \ - if (!p11_rpc_message_write_byte (&_msg, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG(val) \ - if (!p11_rpc_message_write_ulong (&_msg, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_STRING(val) \ - if (!p11_rpc_message_write_zero_string (&_msg, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_BYTE_BUFFER(arr, len) \ - if (len == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!p11_rpc_message_write_byte_buffer (&_msg, arr ? *len : 0)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_BYTE_ARRAY(arr, len) \ - if (len != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!p11_rpc_message_write_byte_array (&_msg, arr, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG_BUFFER(arr, len) \ - if (len == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!p11_rpc_message_write_ulong_buffer (&_msg, arr ? *len : 0)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG_ARRAY(arr, len) \ - if (len != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; }\ - if (!p11_rpc_message_write_ulong_array (&_msg, arr, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ATTRIBUTE_BUFFER(arr, num) \ - if (num != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!p11_rpc_message_write_attribute_buffer (&_msg, (arr), (num))) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ATTRIBUTE_ARRAY(arr, num) \ - if (num != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!p11_rpc_message_write_attribute_array (&_msg, (arr), (num))) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_MECHANISM_TYPE(val) \ - if(!mechanism_is_supported (val)) \ - { _ret = CKR_MECHANISM_INVALID; goto _cleanup; } \ - if (!p11_rpc_message_write_ulong (&_msg, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_MECHANISM(val) \ - if (val == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - _ret = proto_write_mechanism (&_msg, val); \ - if (_ret != CKR_OK) goto _cleanup; - - - -#define OUT_ULONG(val) \ - if (val == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK && !p11_rpc_message_read_ulong (&_msg, val)) \ - _ret = PARSE_ERROR; - -#define OUT_BYTE_ARRAY(arr, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_byte_array (&_msg, (arr), (len), *(len)); - -#define OUT_ULONG_ARRAY(a, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_ulong_array (&_msg, (a), (len), *(len)); - -#define OUT_ATTRIBUTE_ARRAY(arr, num) \ - if (_ret == CKR_OK) \ - _ret = proto_read_attribute_array (&_msg, (arr), (num)); - -#define OUT_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_info (&_msg, info); - -#define OUT_SLOT_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_slot_info (&_msg, info); - -#define OUT_TOKEN_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_token_info (&_msg, info); - -#define OUT_SESSION_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_sesssion_info (&_msg, info); - -#define OUT_MECHANISM_TYPE_ARRAY(arr, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_ulong_array (&_msg, (arr), (len), *(len)); \ - if (_ret == CKR_OK && arr) \ - mechanism_list_purge (arr, len); - -#define OUT_MECHANISM_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_mechanism_info (&_msg, info); - - -/* ------------------------------------------------------------------- - * INITIALIZATION and 'GLOBAL' CALLS - */ - -static CK_RV -rpc_C_Initialize (CK_X_FUNCTION_LIST *self, - CK_VOID_PTR init_args) -{ - rpc_client *module = ((p11_virtual *)self)->lower_module; - CK_C_INITIALIZE_ARGS_PTR args = NULL; - void *reserved = NULL; - CK_RV ret = CKR_OK; - p11_rpc_message msg; - - assert (module != NULL); - p11_debug ("C_Initialize: enter"); - - if (init_args != NULL) { - int supplied_ok; - - /* - * pReserved is either a string or NULL. Other cases - * should be rejected by the caller of this function. - */ - args = init_args; - - /* ALL supplied function pointers need to have the value either NULL or non-NULL. */ - supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL && - args->LockMutex == NULL && args->UnlockMutex == NULL) || - (args->CreateMutex != NULL && args->DestroyMutex != NULL && - args->LockMutex != NULL && args->UnlockMutex != NULL); - if (!supplied_ok) { - p11_message ("invalid set of mutex calls supplied"); - return CKR_ARGUMENTS_BAD; - } - - /* - * When the CKF_OS_LOCKING_OK flag isn't set return an error. - * We must be able to use our mutex functionality. - */ - if (!(args->flags & CKF_OS_LOCKING_OK)) { - p11_message ("can't do without os locking"); - return CKR_CANT_LOCK; - } - - if (args->pReserved) - reserved = args->pReserved; - } - - p11_mutex_lock (&module->mutex); - - if (module->initialized_forkid != 0) { - /* This process has called C_Initialize already */ - if (p11_forkid == module->initialized_forkid) { - p11_message ("C_Initialize called twice for same process"); - ret = CKR_CRYPTOKI_ALREADY_INITIALIZED; - goto done; - } - } - - /* Call out to initialize client callback */ - assert (module->vtable->connect != NULL); - ret = (module->vtable->connect) (module->vtable, reserved); - - /* Successfully initialized */ - if (ret == CKR_OK) { - module->initialized_forkid = p11_forkid; - module->initialize_done = true; - - /* Server doesn't exist, initialize but don't call */ - } else if (ret == CKR_DEVICE_REMOVED) { - module->initialized_forkid = p11_forkid; - module->initialize_done = false; - ret = CKR_OK; - goto done; - - } else { - goto done; - } - - /* If we don't have read and write fds now, then initialize other side */ - ret = call_prepare (module, &msg, P11_RPC_CALL_C_Initialize); - if (ret == CKR_OK) - if (!p11_rpc_message_write_byte_array (&msg, P11_RPC_HANDSHAKE, P11_RPC_HANDSHAKE_LEN)) - ret = CKR_HOST_MEMORY; - if (ret == CKR_OK) { - if (!p11_rpc_message_write_byte (&msg, reserved != NULL)) - ret = CKR_HOST_MEMORY; - } - if (ret == CKR_OK) { - char *reserved_string = ""; - if (reserved != NULL) - reserved_string = (char *) reserved; - if (!p11_rpc_message_write_byte_array (&msg, (CK_BYTE_PTR) reserved_string, strlen (reserved_string) + 1)) - ret = CKR_HOST_MEMORY; - } - if (ret == CKR_OK) - ret = call_run (module, &msg); - call_done (module, &msg, ret); - -done: - /* If failed then unmark initialized */ - if (ret != CKR_OK && ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) - module->initialized_forkid = 0; - - /* If we told our caller that we're initialized, but not really, then finalize */ - if (ret != CKR_OK && module->initialize_done) { - module->initialize_done = false; - assert (module->vtable->disconnect != NULL); - (module->vtable->disconnect) (module->vtable, reserved); - } - - p11_mutex_unlock (&module->mutex); - - p11_debug ("C_Initialize: %lu", ret); - return ret; -} - -static CK_RV -rpc_C_Finalize (CK_X_FUNCTION_LIST *self, - CK_VOID_PTR reserved) -{ - rpc_client *module = ((p11_virtual *)self)->lower_module; - CK_RV ret = CKR_OK; - p11_rpc_message msg; - - p11_debug ("C_Finalize: enter"); - return_val_if_fail (module->initialized_forkid == p11_forkid, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail (!reserved, CKR_ARGUMENTS_BAD); - - p11_mutex_lock (&module->mutex); - - if (module->initialize_done) { - ret = call_prepare (module, &msg, P11_RPC_CALL_C_Finalize); - if (ret == CKR_OK) - ret = call_run (module, &msg); - call_done (module, &msg, ret); - if (ret != CKR_OK) - p11_message ("finalizing rpc module returned an error: %lu", ret); - - module->initialize_done = false; - assert (module->vtable->disconnect != NULL); - (module->vtable->disconnect) (module->vtable, reserved); - } - - module->initialized_forkid = 0; - - p11_mutex_unlock (&module->mutex); - - p11_debug ("C_Finalize: %lu", CKR_OK); - return CKR_OK; -} - -static CK_RV -fill_stand_in_info (CK_INFO_PTR info) -{ - static CK_INFO stand_in_info = { - { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, - "p11-kit ", - 0, - "p11-kit (no connection) ", - { 1, 1 }, - }; - memcpy (info, &stand_in_info, sizeof (CK_INFO)); - return CKR_OK; - -} - -static CK_RV -rpc_C_GetInfo (CK_X_FUNCTION_LIST *self, - CK_INFO_PTR info) -{ - return_val_if_fail (info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetInfo, self, fill_stand_in_info (info)); - PROCESS_CALL; - OUT_INFO (info); - END_CALL; -} - -static CK_RV -rpc_C_GetSlotList (CK_X_FUNCTION_LIST *self, - CK_BBOOL token_present, - CK_SLOT_ID_PTR slot_list, - CK_ULONG_PTR count) -{ - return_val_if_fail (count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetSlotList, self, (*count = 0, CKR_OK)); - IN_BYTE (token_present); - IN_ULONG_BUFFER (slot_list, count); - PROCESS_CALL; - OUT_ULONG_ARRAY (slot_list, count); - END_CALL; -} - -static CK_RV -rpc_C_GetSlotInfo (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_SLOT_INFO_PTR info) -{ - return_val_if_fail (info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetSlotInfo, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - PROCESS_CALL; - OUT_SLOT_INFO (info); - END_CALL; -} - -static CK_RV -rpc_C_GetTokenInfo (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_TOKEN_INFO_PTR info) -{ - return_val_if_fail (info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetTokenInfo, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - PROCESS_CALL; - OUT_TOKEN_INFO (info); - END_CALL; -} - -static CK_RV -rpc_C_GetMechanismList (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_MECHANISM_TYPE_PTR mechanism_list, - CK_ULONG_PTR count) -{ - return_val_if_fail (count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetMechanismList, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - IN_ULONG_BUFFER (mechanism_list, count); - PROCESS_CALL; - OUT_MECHANISM_TYPE_ARRAY (mechanism_list, count); - END_CALL; -} - -static CK_RV -rpc_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR info) -{ - return_val_if_fail (info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetMechanismInfo, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - IN_MECHANISM_TYPE (type); - PROCESS_CALL; - OUT_MECHANISM_INFO (info); - END_CALL; -} - -static CK_RV -rpc_C_InitToken (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, - CK_UTF8CHAR_PTR label) -{ - BEGIN_CALL_OR (C_InitToken, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - IN_BYTE_ARRAY (pin, pin_len); - IN_STRING (label); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self, - CK_FLAGS flags, - CK_SLOT_ID_PTR slot, - CK_VOID_PTR reserved) -{ - return_val_if_fail (slot, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_WaitForSlotEvent, self, CKR_DEVICE_REMOVED); - IN_ULONG (flags); - PROCESS_CALL; - OUT_ULONG (slot); - END_CALL; -} - -static CK_RV -rpc_C_OpenSession (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id, - CK_FLAGS flags, - CK_VOID_PTR user_data, - CK_NOTIFY callback, - CK_SESSION_HANDLE_PTR session) -{ - return_val_if_fail (session, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_OpenSession, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - IN_ULONG (flags); - PROCESS_CALL; - OUT_ULONG (session); - END_CALL; -} - -static CK_RV -rpc_C_CloseSession (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session) -{ - BEGIN_CALL_OR (C_CloseSession, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, - CK_SLOT_ID slot_id) -{ - BEGIN_CALL_OR (C_CloseAllSessions, self, CKR_SLOT_ID_INVALID); - IN_ULONG (slot_id); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetSessionInfo (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_SESSION_INFO_PTR info) -{ - return_val_if_fail (info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetSessionInfo, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - PROCESS_CALL; - OUT_SESSION_INFO (info); - END_CALL; -} - -static CK_RV -rpc_C_InitPIN (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_UTF8CHAR_PTR pin, - CK_ULONG pin_len) -{ - BEGIN_CALL_OR (C_InitPIN, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (pin, pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SetPIN (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_UTF8CHAR_PTR old_pin, - CK_ULONG old_pin_len, - CK_UTF8CHAR_PTR new_pin, - CK_ULONG new_pin_len) -{ - BEGIN_CALL_OR (C_SetPIN, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (old_pin, old_pin_len); - IN_BYTE_ARRAY (new_pin, new_pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetOperationState (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR operation_state, - CK_ULONG_PTR operation_state_len) -{ - return_val_if_fail (operation_state_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetOperationState, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (operation_state, operation_state_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (operation_state, operation_state_len); - END_CALL; -} - -static CK_RV -rpc_C_SetOperationState (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR operation_state, - CK_ULONG operation_state_len, - CK_OBJECT_HANDLE encryption_key, - CK_OBJECT_HANDLE authentication_key) -{ - BEGIN_CALL_OR (C_SetOperationState, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (operation_state, operation_state_len); - IN_ULONG (encryption_key); - IN_ULONG (authentication_key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Login (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_USER_TYPE user_type, - CK_UTF8CHAR_PTR pin, - CK_ULONG pin_len) -{ - BEGIN_CALL_OR (C_Login, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (user_type); - IN_BYTE_ARRAY (pin, pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Logout (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session) -{ - BEGIN_CALL_OR (C_Logout, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_CreateObject (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_ATTRIBUTE_PTR template, - CK_ULONG count, - CK_OBJECT_HANDLE_PTR new_object) -{ - return_val_if_fail (new_object, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_CreateObject, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - OUT_ULONG (new_object); - END_CALL; -} - -static CK_RV -rpc_C_CopyObject (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, - CK_ULONG count, - CK_OBJECT_HANDLE_PTR new_object) -{ - return_val_if_fail (new_object, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_CopyObject, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (object); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - OUT_ULONG (new_object); - END_CALL; -} - - -static CK_RV -rpc_C_DestroyObject (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE object) -{ - BEGIN_CALL_OR (C_DestroyObject, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (object); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetObjectSize (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE object, - CK_ULONG_PTR size) -{ - return_val_if_fail (size, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_GetObjectSize, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (object); - PROCESS_CALL; - OUT_ULONG (size); - END_CALL; -} - -static CK_RV -rpc_C_GetAttributeValue (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, - CK_ULONG count) -{ - BEGIN_CALL_OR (C_GetAttributeValue, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (object); - IN_ATTRIBUTE_BUFFER (template, count); - PROCESS_CALL; - OUT_ATTRIBUTE_ARRAY (template, count); - END_CALL; -} - -static CK_RV -rpc_C_SetAttributeValue (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, - CK_ULONG count) -{ - BEGIN_CALL_OR (C_SetAttributeValue, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (object); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_FindObjectsInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_ATTRIBUTE_PTR template, - CK_ULONG count) -{ - BEGIN_CALL_OR (C_FindObjectsInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_FindObjects (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE_PTR objects, - CK_ULONG max_count, - CK_ULONG_PTR count) -{ - /* HACK: To fix a stupid gcc warning */ - CK_ULONG_PTR address_of_max_count = &max_count; - - return_val_if_fail (count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_FindObjects, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG_BUFFER (objects, address_of_max_count); - PROCESS_CALL; - *count = max_count; - OUT_ULONG_ARRAY (objects, count); - END_CALL; -} - -static CK_RV -rpc_C_FindObjectsFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session) -{ - BEGIN_CALL_OR (C_FindObjectsFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_EncryptInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_EncryptInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Encrypt (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR data, - CK_ULONG data_len, - CK_BYTE_PTR encrypted_data, - CK_ULONG_PTR encrypted_data_len) -{ - return_val_if_fail (encrypted_data_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_Encrypt, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (data, data_len); - IN_BYTE_BUFFER (encrypted_data, encrypted_data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (encrypted_data, encrypted_data_len); - END_CALL; -} - -static CK_RV -rpc_C_EncryptUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len, - CK_BYTE_PTR encrypted_part, - CK_ULONG_PTR encrypted_part_len) -{ - return_val_if_fail (encrypted_part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_EncryptUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - IN_BYTE_BUFFER (encrypted_part, encrypted_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (encrypted_part, encrypted_part_len); - END_CALL; -} - -static CK_RV -rpc_C_EncryptFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR last_part, - CK_ULONG_PTR last_part_len) -{ - return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_EncryptFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (last_part, last_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (last_part, last_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_DecryptInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Decrypt (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR enc_data, - CK_ULONG enc_data_len, - CK_BYTE_PTR data, - CK_ULONG_PTR data_len) -{ - return_val_if_fail (data_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_Decrypt, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (enc_data, enc_data_len); - IN_BYTE_BUFFER (data, data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (data, data_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, - CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DecryptUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (enc_part, enc_part_len); - IN_BYTE_BUFFER (part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR last_part, - CK_ULONG_PTR last_part_len) -{ - return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DecryptFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (last_part, last_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (last_part, last_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism) -{ - BEGIN_CALL_OR (C_DigestInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Digest (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR data, - CK_ULONG data_len, - CK_BYTE_PTR digest, - CK_ULONG_PTR digest_len) -{ - return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_Digest, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (data, data_len); - IN_BYTE_BUFFER (digest, digest_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (digest, digest_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len) -{ - BEGIN_CALL_OR (C_DigestUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_DigestKey (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_DigestKey, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_DigestFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR digest, - CK_ULONG_PTR digest_len) -{ - return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DigestFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (digest, digest_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (digest, digest_len); - END_CALL; -} - -static CK_RV -rpc_C_SignInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_SignInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Sign (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR data, - CK_ULONG data_len, - CK_BYTE_PTR signature, - CK_ULONG_PTR signature_len) -{ - return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_Sign, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (data, data_len); - IN_BYTE_BUFFER (signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_SignUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len) -{ - return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_SignUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SignFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR signature, - CK_ULONG_PTR signature_len) -{ - return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_SignFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_SignRecoverInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_SignRecoverInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SignRecover (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR data, - CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) -{ - return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_SignRecover, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (data, data_len); - IN_BYTE_BUFFER (signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_VerifyInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_VerifyInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Verify (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR data, - CK_ULONG data_len, - CK_BYTE_PTR signature, - CK_ULONG signature_len) -{ - BEGIN_CALL_OR (C_Verify, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (data, data_len); - IN_BYTE_ARRAY (signature, signature_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len) -{ - BEGIN_CALL_OR (C_VerifyUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyFinal (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR signature, - CK_ULONG signature_len) -{ - BEGIN_CALL_OR (C_VerifyFinal, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (signature, signature_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyRecoverInit (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - BEGIN_CALL_OR (C_VerifyRecoverInit, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyRecover (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR signature, - CK_ULONG signature_len, - CK_BYTE_PTR data, - CK_ULONG_PTR data_len) -{ - return_val_if_fail (data_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_VerifyRecover, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (signature, signature_len); - IN_BYTE_BUFFER (data, data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (data, data_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestEncryptUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len, - CK_BYTE_PTR enc_part, - CK_ULONG_PTR enc_part_len) -{ - return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DigestEncryptUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - IN_BYTE_BUFFER (enc_part, enc_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (enc_part, enc_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptDigestUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, - CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DecryptDigestUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (enc_part, enc_part_len); - IN_BYTE_BUFFER (part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_SignEncryptUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR part, - CK_ULONG part_len, - CK_BYTE_PTR enc_part, - CK_ULONG_PTR enc_part_len) -{ - return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_SignEncryptUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (part, part_len); - IN_BYTE_BUFFER (enc_part, enc_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (enc_part, enc_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptVerifyUpdate (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, - CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_DecryptVerifyUpdate, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (enc_part, enc_part_len); - IN_BYTE_BUFFER (part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_GenerateKey (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR template, - CK_ULONG count, - CK_OBJECT_HANDLE_PTR key) -{ - BEGIN_CALL_OR (C_GenerateKey, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - OUT_ULONG (key); - END_CALL; -} - -static CK_RV -rpc_C_GenerateKeyPair (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR pub_template, - CK_ULONG pub_count, - CK_ATTRIBUTE_PTR priv_template, - CK_ULONG priv_count, - CK_OBJECT_HANDLE_PTR pub_key, - CK_OBJECT_HANDLE_PTR priv_key) -{ - BEGIN_CALL_OR (C_GenerateKeyPair, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ATTRIBUTE_ARRAY (pub_template, pub_count); - IN_ATTRIBUTE_ARRAY (priv_template, priv_count); - PROCESS_CALL; - OUT_ULONG (pub_key); - OUT_ULONG (priv_key); - END_CALL; -} - -static CK_RV -rpc_C_WrapKey (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE wrapping_key, - CK_OBJECT_HANDLE key, - CK_BYTE_PTR wrapped_key, - CK_ULONG_PTR wrapped_key_len) -{ - return_val_if_fail (wrapped_key_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL_OR (C_WrapKey, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (wrapping_key); - IN_ULONG (key); - IN_BYTE_BUFFER (wrapped_key, wrapped_key_len); - PROCESS_CALL; - OUT_BYTE_ARRAY (wrapped_key, wrapped_key_len); - END_CALL; -} - -static CK_RV -rpc_C_UnwrapKey (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE unwrapping_key, - CK_BYTE_PTR wrapped_key, - CK_ULONG wrapped_key_len, - CK_ATTRIBUTE_PTR template, - CK_ULONG count, - CK_OBJECT_HANDLE_PTR key) -{ - BEGIN_CALL_OR (C_UnwrapKey, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (unwrapping_key); - IN_BYTE_ARRAY (wrapped_key, wrapped_key_len); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - OUT_ULONG (key); - END_CALL; -} - -static CK_RV -rpc_C_DeriveKey (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE base_key, - CK_ATTRIBUTE_PTR template, - CK_ULONG count, - CK_OBJECT_HANDLE_PTR key) -{ - BEGIN_CALL_OR (C_DeriveKey, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_MECHANISM (mechanism); - IN_ULONG (base_key); - IN_ATTRIBUTE_ARRAY (template, count); - PROCESS_CALL; - OUT_ULONG (key); - END_CALL; -} - -static CK_RV -rpc_C_SeedRandom (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR seed, - CK_ULONG seed_len) -{ - BEGIN_CALL_OR (C_SeedRandom, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_ARRAY (seed, seed_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GenerateRandom (CK_X_FUNCTION_LIST *self, - CK_SESSION_HANDLE session, - CK_BYTE_PTR random_data, - CK_ULONG random_len) -{ - CK_ULONG_PTR address = &random_len; - - BEGIN_CALL_OR (C_GenerateRandom, self, CKR_SESSION_HANDLE_INVALID); - IN_ULONG (session); - IN_BYTE_BUFFER (random_data, address); - PROCESS_CALL; - OUT_BYTE_ARRAY (random_data, address); - END_CALL; -} - -static CK_X_FUNCTION_LIST rpc_functions = { - { -1, -1 }, - rpc_C_Initialize, - rpc_C_Finalize, - rpc_C_GetInfo, - rpc_C_GetSlotList, - rpc_C_GetSlotInfo, - rpc_C_GetTokenInfo, - rpc_C_GetMechanismList, - rpc_C_GetMechanismInfo, - rpc_C_InitToken, - rpc_C_InitPIN, - rpc_C_SetPIN, - rpc_C_OpenSession, - rpc_C_CloseSession, - rpc_C_CloseAllSessions, - rpc_C_GetSessionInfo, - rpc_C_GetOperationState, - rpc_C_SetOperationState, - rpc_C_Login, - rpc_C_Logout, - rpc_C_CreateObject, - rpc_C_CopyObject, - rpc_C_DestroyObject, - rpc_C_GetObjectSize, - rpc_C_GetAttributeValue, - rpc_C_SetAttributeValue, - rpc_C_FindObjectsInit, - rpc_C_FindObjects, - rpc_C_FindObjectsFinal, - rpc_C_EncryptInit, - rpc_C_Encrypt, - rpc_C_EncryptUpdate, - rpc_C_EncryptFinal, - rpc_C_DecryptInit, - rpc_C_Decrypt, - rpc_C_DecryptUpdate, - rpc_C_DecryptFinal, - rpc_C_DigestInit, - rpc_C_Digest, - rpc_C_DigestUpdate, - rpc_C_DigestKey, - rpc_C_DigestFinal, - rpc_C_SignInit, - rpc_C_Sign, - rpc_C_SignUpdate, - rpc_C_SignFinal, - rpc_C_SignRecoverInit, - rpc_C_SignRecover, - rpc_C_VerifyInit, - rpc_C_Verify, - rpc_C_VerifyUpdate, - rpc_C_VerifyFinal, - rpc_C_VerifyRecoverInit, - rpc_C_VerifyRecover, - rpc_C_DigestEncryptUpdate, - rpc_C_DecryptDigestUpdate, - rpc_C_SignEncryptUpdate, - rpc_C_DecryptVerifyUpdate, - rpc_C_GenerateKey, - rpc_C_GenerateKeyPair, - rpc_C_WrapKey, - rpc_C_UnwrapKey, - rpc_C_DeriveKey, - rpc_C_SeedRandom, - rpc_C_GenerateRandom, - rpc_C_WaitForSlotEvent, -}; - -static void -rpc_client_free (void *data) -{ - rpc_client *client = data; - p11_mutex_uninit (&client->mutex); - free (client); -} - -bool -p11_rpc_client_init (p11_virtual *virt, - p11_rpc_client_vtable *vtable) -{ - rpc_client *client; - - p11_message_clear (); - - return_val_if_fail (vtable != NULL, false); - return_val_if_fail (vtable->connect != NULL, false); - return_val_if_fail (vtable->transport != NULL, false); - return_val_if_fail (vtable->disconnect != NULL, false); - - P11_RPC_CHECK_CALLS (); - - client = calloc (1, sizeof (rpc_client)); - return_val_if_fail (client != NULL, false); - - p11_mutex_init (&client->mutex); - client->vtable = vtable; - - p11_virtual_init (virt, &rpc_functions, client, rpc_client_free); - return true; -} |