diff options
Diffstat (limited to 'p11-kit/tests/test-rpc.c')
-rw-r--r-- | p11-kit/tests/test-rpc.c | 1061 |
1 files changed, 0 insertions, 1061 deletions
diff --git a/p11-kit/tests/test-rpc.c b/p11-kit/tests/test-rpc.c deleted file mode 100644 index 0ce2c55..0000000 --- a/p11-kit/tests/test-rpc.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* - * Copyright (c) 2012 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 <stef@thewalter.net> - */ - -#include "config.h" -#include "test.h" - -#include "debug.h" -#include "library.h" -#include "message.h" -#include "mock.h" -#include "p11-kit.h" -#include "private.h" -#include "rpc.h" -#include "rpc-message.h" -#include "virtual.h" - -#include <sys/types.h> -#include <sys/wait.h> -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -static void -test_new_free (void) -{ - p11_buffer *buf; - - buf = p11_rpc_buffer_new (0); - - assert_ptr_not_null (buf->data); - assert_num_eq (0, buf->len); - assert_num_eq (0, buf->flags); - assert (buf->size == 0); - assert_ptr_not_null (buf->ffree); - assert_ptr_not_null (buf->frealloc); - - p11_rpc_buffer_free (buf); -} - -static void -test_uint16 (void) -{ - p11_buffer buffer; - uint16_t val = 0xFFFF; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - next = 0; - ret = p11_rpc_buffer_get_uint16 (&buffer, &next, &val); - assert_num_eq (false, ret); - assert_num_eq (0, next); - assert_num_eq (0xFFFF, val); - - p11_buffer_reset (&buffer, 0); - - ret = p11_rpc_buffer_set_uint16 (&buffer, 0, 0x6789); - assert_num_eq (false, ret); - - p11_buffer_reset (&buffer, 0); - - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - - p11_rpc_buffer_add_uint16 (&buffer, 0x6789); - assert_num_eq (9, buffer.len); - assert (!p11_buffer_failed (&buffer)); - - next = 7; - ret = p11_rpc_buffer_get_uint16 (&buffer, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (9, next); - assert_num_eq (0x6789, val); - - p11_buffer_uninit (&buffer); -} - -static void -test_uint16_static (void) -{ - p11_buffer buf = { (unsigned char *)"pad0\x67\x89", 6, }; - uint16_t val = 0xFFFF; - size_t next; - bool ret; - - next = 4; - ret = p11_rpc_buffer_get_uint16 (&buf, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (6, next); - assert_num_eq (0x6789, val); -} - -static void -test_uint32 (void) -{ - p11_buffer buffer; - uint32_t val = 0xFFFFFFFF; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - next = 0; - ret = p11_rpc_buffer_get_uint32 (&buffer, &next, &val); - assert_num_eq (false, ret); - assert_num_eq (0, next); - assert_num_eq (0xFFFFFFFF, val); - - p11_buffer_reset (&buffer, 0); - - ret = p11_rpc_buffer_set_uint32 (&buffer, 0, 0x12345678); - assert_num_eq (false, ret); - - p11_buffer_reset (&buffer, 0); - - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - - p11_rpc_buffer_add_uint32 (&buffer, 0x12345678); - assert_num_eq (11, buffer.len); - assert (!p11_buffer_failed (&buffer)); - - next = 7; - ret = p11_rpc_buffer_get_uint32 (&buffer, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (11, next); - assert_num_eq (0x12345678, val); - - p11_buffer_uninit (&buffer); -} - -static void -test_uint32_static (void) -{ - p11_buffer buf = { (unsigned char *)"pad0\x23\x45\x67\x89", 8, }; - uint32_t val = 0xFFFFFFFF; - size_t next; - bool ret; - - next = 4; - ret = p11_rpc_buffer_get_uint32 (&buf, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (8, next); - assert_num_eq (0x23456789, val); -} - -static void -test_uint64 (void) -{ - p11_buffer buffer; - uint64_t val = 0xFFFFFFFFFFFFFFFF; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - next = 0; - ret = p11_rpc_buffer_get_uint64 (&buffer, &next, &val); - assert_num_eq (0, ret); - assert_num_eq (0, next); - assert (0xFFFFFFFFFFFFFFFF == val); - - p11_buffer_reset (&buffer, 0); - - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - - p11_rpc_buffer_add_uint64 (&buffer, 0x0123456708ABCDEF); - assert_num_eq (15, buffer.len); - assert (!p11_buffer_failed (&buffer)); - - next = 7; - ret = p11_rpc_buffer_get_uint64 (&buffer, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (15, next); - assert (0x0123456708ABCDEF == val); - - p11_buffer_uninit (&buffer); -} - -static void -test_uint64_static (void) -{ - p11_buffer buf = { (unsigned char *)"pad0\x89\x67\x45\x23\x11\x22\x33\x44", 12, }; - uint64_t val = 0xFFFFFFFFFFFFFFFF; - size_t next; - bool ret; - - next = 4; - ret = p11_rpc_buffer_get_uint64 (&buf, &next, &val); - assert_num_eq (true, ret); - assert_num_eq (12, next); - assert (0x8967452311223344 == val); -} - -static void -test_byte_array (void) -{ - p11_buffer buffer; - unsigned char bytes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - - const unsigned char *val; - size_t length = ~0; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - /* Invalid read */ - - next = 0; - ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length); - assert_num_eq (false, ret); - assert_num_eq (0, next); - assert_num_eq (~0, length); - - /* Test full array */ - - p11_buffer_reset (&buffer, 0); - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - - p11_rpc_buffer_add_byte_array (&buffer, bytes, 32); - assert_num_eq (43, buffer.len); - assert (!p11_buffer_failed (&buffer)); - - next = 7; - ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length); - assert_num_eq (true, ret); - assert_num_eq (43, next); - assert_num_eq (32, length); - assert (memcmp (val, bytes, 32) == 0); - - p11_buffer_uninit (&buffer); -} - -static void -test_byte_array_null (void) -{ - p11_buffer buffer; - const unsigned char *val; - size_t length = ~0; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - p11_buffer_reset (&buffer, 0); - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - - p11_rpc_buffer_add_byte_array (&buffer, NULL, 0); - assert_num_eq (11, buffer.len); - assert (!p11_buffer_failed (&buffer)); - - next = 7; - ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length); - assert_num_eq (true, ret); - assert_num_eq (11, next); - assert_num_eq (0, length); - assert_ptr_eq (NULL, (void*)val); - - p11_buffer_uninit (&buffer); -} - -static void -test_byte_array_too_long (void) -{ - p11_buffer buffer; - const unsigned char *val = NULL; - size_t length = ~0; - size_t next; - bool ret; - - p11_buffer_init (&buffer, 0); - - p11_buffer_reset (&buffer, 0); - p11_buffer_add (&buffer, (unsigned char *)"padding", 7); - assert (!p11_buffer_failed (&buffer)); - - /* Passing a too short buffer here shouldn't matter, as length is checked for sanity */ - p11_rpc_buffer_add_byte_array (&buffer, (unsigned char *)"", 0x9fffffff); - assert (p11_buffer_failed (&buffer)); - - /* Force write a too long byte arary to buffer */ - p11_buffer_reset (&buffer, 0); - p11_rpc_buffer_add_uint32 (&buffer, 0x9fffffff); - - next = 0; - ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length); - assert_num_eq (false, ret); - assert_num_eq (0, next); - assert_num_eq (~0, length); - assert_ptr_eq (NULL, (void*)val); - - p11_buffer_uninit (&buffer); -} - -static void -test_byte_array_static (void) -{ - unsigned char data[] = { 'p', 'a', 'd', 0x00, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; - p11_buffer buf = { data, 0x40, }; - const unsigned char *val; - size_t length = ~0; - size_t next; - bool ret; - - next = 4; - ret = p11_rpc_buffer_get_byte_array (&buf, &next, &val, &length); - assert_num_eq (true, ret); - assert_num_eq (40, next); - assert_num_eq (32, length); - assert (memcmp (data + 8, val, 32) == 0); -} - -static p11_virtual base; -static pid_t rpc_initialized = 0; - -static CK_RV -rpc_initialize (p11_rpc_client_vtable *vtable, - void *init_reserved) -{ - pid_t pid = getpid (); - - assert_str_eq (vtable->data, "vtable-data"); - assert_num_cmp (pid, !=, rpc_initialized); - rpc_initialized = pid; - - return CKR_OK; -} - -static CK_RV -rpc_initialize_fails (p11_rpc_client_vtable *vtable, - void *init_reserved) -{ - pid_t pid = getpid (); - - assert_str_eq (vtable->data, "vtable-data"); - assert_num_cmp (pid, !=, rpc_initialized); - return CKR_FUNCTION_FAILED; -} - -static CK_RV -rpc_initialize_device_removed (p11_rpc_client_vtable *vtable, - void *init_reserved) -{ - pid_t pid = getpid (); - - assert_str_eq (vtable->data, "vtable-data"); - assert_num_cmp (pid, !=, rpc_initialized); - return CKR_DEVICE_REMOVED; -} - -static CK_RV -rpc_transport (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - bool ret; - - assert_str_eq (vtable->data, "vtable-data"); - - /* Just pass directly to the server code */ - ret = p11_rpc_server_handle (&base.funcs, request, response); - assert (ret == true); - - return CKR_OK; -} - -static void -rpc_finalize (p11_rpc_client_vtable *vtable, - void *fini_reserved) -{ - pid_t pid = getpid (); - - assert_str_eq (vtable->data, "vtable-data"); - assert_num_cmp (pid, ==, rpc_initialized); - rpc_initialized = 0; -} - -static void -test_initialize (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize }; - pid_t pid = getpid (); - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - rpc_initialized = 0; - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - rv = mixin.funcs.C_Initialize (&mixin.funcs, NULL); - assert (rv == CKR_OK); - assert_num_eq (pid, rpc_initialized); - - rv = mixin.funcs.C_Finalize (&mixin.funcs, NULL); - assert (rv == CKR_OK); - assert_num_cmp (pid, !=, rpc_initialized); - - p11_virtual_uninit (&mixin); -} - -static void -test_not_initialized (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize }; - p11_virtual mixin; - CK_INFO info; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - rpc_initialized = 0; - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - rv = (mixin.funcs.C_GetInfo) (&mixin.funcs, &info); - assert (rv == CKR_CRYPTOKI_NOT_INITIALIZED); - - p11_virtual_uninit (&mixin); -} - -static void -test_initialize_fails_on_client (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize_fails, rpc_transport, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - rpc_initialized = 0; - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_FUNCTION_FAILED); - assert_num_eq (0, rpc_initialized); - - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_fails (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - return CKR_FUNCTION_REJECTED; -} - -static void -test_transport_fails (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_fails, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - rpc_initialized = 0; - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_FUNCTION_REJECTED); - assert_num_eq (0, rpc_initialized); - - p11_virtual_uninit (&mixin); -} - -static void -test_initialize_fails_on_server (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - base.funcs.C_Initialize = mock_X_Initialize__fails; - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_FUNCTION_FAILED); - assert_num_eq (0, rpc_initialized); - - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_bad_parse (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - int rc; - - assert_str_eq (vtable->data, "vtable-data"); - - /* Just zero bytes is an invalid message */ - rc = p11_buffer_reset (response, 2); - assert (rc >= 0); - - memset (response->data, 0, 2); - response->len = 2; - return CKR_OK; -} - -static void -test_transport_bad_parse (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_bad_parse, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - rpc_initialized = 0; - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - p11_kit_be_quiet (); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_DEVICE_ERROR); - assert_num_eq (0, rpc_initialized); - - p11_message_loud (); - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_short_error (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - int rc; - - unsigned char data[] = { - 0x00, 0x00, 0x00, 0x00, /* RPC_CALL_ERROR */ - 0x00, 0x00, 0x00, 0x01, 0x75, /* signature 'u' */ - 0x00, 0x01, /* short error */ - }; - - assert_str_eq (vtable->data, "vtable-data"); - - rc = p11_buffer_reset (response, sizeof (data)); - assert (rc >= 0); - - memcpy (response->data, data, sizeof (data)); - response->len = sizeof (data); - return CKR_OK; -} - -static void -test_transport_short_error (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_short_error, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - p11_kit_be_quiet (); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_DEVICE_ERROR); - assert_num_eq (0, rpc_initialized); - - p11_message_loud (); - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_invalid_error (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - int rc; - - unsigned char data[] = { - 0x00, 0x00, 0x00, 0x00, /* RPC_CALL_ERROR */ - 0x00, 0x00, 0x00, 0x01, 0x75, /* signature 'u' */ - 0x00, 0x00, 0x00, 0x00, /* a CKR_OK error*/ - 0x00, 0x00, 0x00, 0x00, - }; - - assert_str_eq (vtable->data, "vtable-data"); - - rc = p11_buffer_reset (response, sizeof (data)); - assert (rc >= 0); - memcpy (response->data, data, sizeof (data)); - response->len = sizeof (data); - return CKR_OK; -} - -static void -test_transport_invalid_error (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_invalid_error, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - p11_kit_be_quiet (); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_DEVICE_ERROR); - assert_num_eq (0, rpc_initialized); - - p11_message_loud (); - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_wrong_response (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - int rc; - - unsigned char data[] = { - 0x00, 0x00, 0x00, 0x02, /* RPC_CALL_C_Finalize */ - 0x00, 0x00, 0x00, 0x00, /* signature '' */ - }; - - assert_str_eq (vtable->data, "vtable-data"); - - rc = p11_buffer_reset (response, sizeof (data)); - assert (rc >= 0); - memcpy (response->data, data, sizeof (data)); - response->len = sizeof (data); - return CKR_OK; -} - -static void -test_transport_wrong_response (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_wrong_response, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - p11_kit_be_quiet (); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_DEVICE_ERROR); - assert_num_eq (0, rpc_initialized); - - p11_message_loud (); - p11_virtual_uninit (&mixin); -} - -static CK_RV -rpc_transport_bad_contents (p11_rpc_client_vtable *vtable, - p11_buffer *request, - p11_buffer *response) -{ - int rc; - - unsigned char data[] = { - 0x00, 0x00, 0x00, 0x02, /* RPC_CALL_C_GetInfo */ - 0x00, 0x00, 0x00, 0x05, /* signature 'vsusv' */ - 'v', 's', 'u', 's', 'v', - 0x00, 0x00, 0x00, 0x00, /* invalid data */ - }; - - assert_str_eq (vtable->data, "vtable-data"); - - rc = p11_buffer_reset (response, sizeof (data)); - assert (rc >= 0); - memcpy (response->data, data, sizeof (data)); - response->len = sizeof (data); - return CKR_OK; -} - -static void -test_transport_bad_contents (void) -{ - p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_bad_contents, rpc_finalize }; - p11_virtual mixin; - bool ret; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); - - ret = p11_rpc_client_init (&mixin, &vtable); - assert_num_eq (true, ret); - - p11_kit_be_quiet (); - - rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL); - assert (rv == CKR_DEVICE_ERROR); - assert_num_eq (0, rpc_initialized); - - p11_message_loud (); - p11_virtual_uninit (&mixin); -} - -static p11_rpc_client_vtable test_normal_vtable = { - NULL, - rpc_initialize, - rpc_transport, - rpc_finalize, -}; - -static p11_rpc_client_vtable test_device_removed_vtable = { - NULL, - rpc_initialize_device_removed, - rpc_transport, - rpc_finalize, -}; - -static void -mixin_free (void *data) -{ - p11_virtual *mixin = data; - p11_virtual_uninit (mixin); - free (mixin); -} - -static CK_FUNCTION_LIST_PTR -setup_test_rpc_module (p11_rpc_client_vtable *vtable, - CK_FUNCTION_LIST *module_template, - CK_SESSION_HANDLE *session) -{ - CK_FUNCTION_LIST *rpc_module; - p11_virtual *mixin; - CK_RV rv; - - /* Build up our own function list */ - p11_virtual_init (&base, &p11_virtual_base, module_template, NULL); - - mixin = calloc (1, sizeof (p11_virtual)); - assert (mixin != NULL); - - vtable->data = "vtable-data"; - if (!p11_rpc_client_init (mixin, vtable)) - assert_not_reached (); - - rpc_module = p11_virtual_wrap (mixin, mixin_free); - assert_ptr_not_null (rpc_module); - - rv = p11_kit_module_initialize (rpc_module); - assert (rv == CKR_OK); - - if (session) { - rv = (rpc_module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_RW_SESSION | CKF_SERIAL_SESSION, - NULL, NULL, session); - assert (rv == CKR_OK); - } - - return rpc_module; -} - -static CK_FUNCTION_LIST * -setup_mock_module (CK_SESSION_HANDLE *session) -{ - return setup_test_rpc_module (&test_normal_vtable, &mock_module, session); -} - -static void -teardown_mock_module (CK_FUNCTION_LIST *rpc_module) -{ - p11_kit_module_finalize (rpc_module); - p11_virtual_unwrap (rpc_module); -} - -static void -test_get_info_stand_in (void) -{ - CK_FUNCTION_LIST_PTR rpc_module; - CK_INFO info; - CK_RV rv; - char *string; - - rpc_module = setup_test_rpc_module (&test_device_removed_vtable, - &mock_module_no_slots, NULL); - - rv = (rpc_module->C_GetInfo) (&info); - assert (rv == CKR_OK); - - assert_num_eq (CRYPTOKI_VERSION_MAJOR, info.cryptokiVersion.major); - assert_num_eq (CRYPTOKI_VERSION_MINOR, info.cryptokiVersion.minor); - string = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID)); - assert_str_eq ("p11-kit", string); - free (string); - string = p11_kit_space_strdup (info.libraryDescription, sizeof (info.libraryDescription)); - assert_str_eq ("p11-kit (no connection)", string); - free (string); - assert_num_eq (0, info.flags); - assert_num_eq (1, info.libraryVersion.major); - assert_num_eq (1, info.libraryVersion.minor); - - teardown_mock_module (rpc_module); -} - -static void -test_get_slot_list_no_device (void) -{ - CK_FUNCTION_LIST_PTR rpc_module; - CK_SLOT_ID slot_list[8]; - CK_ULONG count; - CK_RV rv; - - rpc_module = setup_test_rpc_module (&test_device_removed_vtable, - &mock_module_no_slots, NULL); - - rv = (rpc_module->C_GetSlotList) (CK_TRUE, NULL, &count); - assert (rv == CKR_OK); - assert_num_eq (0, count); - rv = (rpc_module->C_GetSlotList) (CK_FALSE, NULL, &count); - assert (rv == CKR_OK); - assert_num_eq (0, count); - - count = 8; - rv = (rpc_module->C_GetSlotList) (CK_TRUE, slot_list, &count); - assert (rv == CKR_OK); - assert_num_eq (0, count); - - count = 8; - rv = (rpc_module->C_GetSlotList) (CK_FALSE, slot_list, &count); - assert (rv == CKR_OK); - assert_num_eq (0, count); - - teardown_mock_module (rpc_module); -} - -static void * -invoke_in_thread (void *arg) -{ - CK_FUNCTION_LIST *rpc_module = arg; - CK_INFO info; - CK_RV rv; - - rv = (rpc_module->C_GetInfo) (&info); - assert_num_eq (rv, CKR_OK); - - assert (memcmp (info.manufacturerID, MOCK_INFO.manufacturerID, - sizeof (info.manufacturerID)) == 0); - - return NULL; -} - -static p11_mutex_t delay_mutex; - -static CK_RV -delayed_C_GetInfo (CK_INFO_PTR info) -{ - CK_RV rv; - - p11_sleep_ms (rand () % 100); - - p11_mutex_lock (&delay_mutex); - rv = mock_C_GetInfo (info); - p11_mutex_unlock (&delay_mutex); - - return rv; -} - -static void -test_simultaneous_functions (void) -{ - CK_FUNCTION_LIST real_module; - CK_FUNCTION_LIST *rpc_module; - const int num_threads = 128; - p11_thread_t threads[num_threads]; - int i, ret; - - p11_mutex_init (&delay_mutex); - - memcpy (&real_module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); - real_module.C_GetInfo = delayed_C_GetInfo; - - rpc_module = setup_test_rpc_module (&test_normal_vtable, - &real_module, NULL); - - /* Make the invoked function (above) wait */ - p11_mutex_lock (&delay_mutex); - - for (i = 0; i < num_threads; i++) { - ret = p11_thread_create (threads + i, invoke_in_thread, rpc_module); - assert_num_eq (0, ret); - } - - /* Let the invoked functions return */ - p11_mutex_unlock (&delay_mutex); - - for (i = 0; i < num_threads; i++) - p11_thread_join (threads[i]); - - teardown_mock_module (rpc_module); - p11_mutex_uninit (&delay_mutex); -} - -static void -test_fork_and_reinitialize (void) -{ - CK_FUNCTION_LIST *rpc_module; - CK_INFO info; - int status; - CK_RV rv; - pid_t pid; - int i; - - rpc_module = setup_test_rpc_module (&test_normal_vtable, - &mock_module_no_slots, NULL); - - pid = fork (); - assert_num_cmp (pid, >=, 0); - - /* The child */ - if (pid == 0) { - rv = (rpc_module->C_Initialize) (NULL); - assert_num_eq (CKR_OK, rv); - - for (i = 0; i < 32; i++) { - rv = (rpc_module->C_GetInfo) (&info); - assert_num_eq (CKR_OK, rv); - } - - rv = (rpc_module->C_Finalize) (NULL); - assert_num_eq (CKR_OK, rv); - - _exit (66); - } - - for (i = 0; i < 128; i++) { - rv = (rpc_module->C_GetInfo) (&info); - assert_num_eq (CKR_OK, rv); - } - - assert_num_eq (waitpid (pid, &status, 0), pid); - assert_num_eq (WEXITSTATUS (status), 66); - - teardown_mock_module (rpc_module); -} - -#include "test-mock.c" - -int -main (int argc, - char *argv[]) -{ - CK_MECHANISM_TYPE mechanisms[] = { - CKM_MOCK_CAPITALIZE, - CKM_MOCK_PREFIX, - CKM_MOCK_GENERATE, - CKM_MOCK_WRAP, - CKM_MOCK_DERIVE, - CKM_MOCK_COUNT, - 0, - }; - - mock_module_init (); - p11_library_init (); - - /* Override the mechanisms that the RPC mechanism will handle */ - p11_rpc_mechanisms_override_supported = mechanisms; - - p11_test (test_new_free, "/rpc/new-free"); - p11_test (test_uint16, "/rpc/uint16"); - p11_test (test_uint16_static, "/rpc/uint16-static"); - p11_test (test_uint32, "/rpc/uint32"); - p11_test (test_uint32_static, "/rpc/uint32-static"); - p11_test (test_uint64, "/rpc/uint64"); - p11_test (test_uint64_static, "/rpc/uint64-static"); - p11_test (test_byte_array, "/rpc/byte-array"); - p11_test (test_byte_array_null, "/rpc/byte-array-null"); - p11_test (test_byte_array_too_long, "/rpc/byte-array-too-long"); - p11_test (test_byte_array_static, "/rpc/byte-array-static"); - - p11_test (test_initialize_fails_on_client, "/rpc/initialize-fails-on-client"); - p11_test (test_initialize_fails_on_server, "/rpc/initialize-fails-on-server"); - p11_test (test_initialize, "/rpc/initialize"); - p11_test (test_not_initialized, "/rpc/not-initialized"); - p11_test (test_transport_fails, "/rpc/transport-fails"); - p11_test (test_transport_bad_parse, "/rpc/transport-bad-parse"); - p11_test (test_transport_short_error, "/rpc/transport-short-error"); - p11_test (test_transport_invalid_error, "/rpc/transport-invalid-error"); - p11_test (test_transport_wrong_response, "/rpc/transport-wrong-response"); - p11_test (test_transport_bad_contents, "/rpc/transport-bad-contents"); - p11_test (test_get_info_stand_in, "/rpc/get-info-stand-in"); - p11_test (test_get_slot_list_no_device, "/rpc/get-slot-list-no-device"); - p11_test (test_simultaneous_functions, "/rpc/simultaneous-functions"); - p11_test (test_fork_and_reinitialize, "/rpc/fork-and-reinitialize"); - - test_mock_add_tests ("/rpc"); - - return p11_test_run (argc, argv); -} |