1 /*
2 * Copyright (c) 2012 Stefan Walter
3 * Copyright (C) 2012-2017 Red Hat Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 * * Redistributions in binary form must reproduce the
13 * above copyright notice, this list of conditions and
14 * the following disclaimer in the documentation and/or
15 * other materials provided with the distribution.
16 * * The names of contributors to this software may not be
17 * used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 * DAMAGE.
32 *
33 * Author: Stef Walter <stef@thewalter.net>
34 */
35
36 #include "config.h"
37 #include "test.h"
38
39 #include "debug.h"
40 #include "library.h"
41 #include "message.h"
42 #include "mock.h"
43 #include "p11-kit.h"
44 #include "private.h"
45 #include "rpc.h"
46 #include "rpc-message.h"
47 #include "virtual.h"
48
49 #include <sys/types.h>
50 #ifdef OS_UNIX
51 #include <sys/wait.h>
52 #endif
53 #include <assert.h>
54 #include <limits.h>
55 #include <string.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #ifdef OS_UNIX
59 #include <unistd.h>
60 #endif
61
62 #define ELEMS(x) (sizeof (x) / sizeof (x[0]))
63
64 #if SIZEOF_UNSIGNED_LONG == 8
65 #define ULONG_VAL 0x0123456708ABCDEF
66 #elif SIZEOF_UNSIGNED_LONG == 4
67 #define ULONG_VAL 0x01234567
68 #else
69 #error "unsupported size of CK_ULONG"
70 #endif
71
72 static void
test_new_free(void)73 test_new_free (void)
74 {
75 p11_buffer *buf;
76
77 buf = p11_rpc_buffer_new (0);
78
79 assert_ptr_not_null (buf->data);
80 assert_num_eq (0, buf->len);
81 assert_num_eq (0, buf->flags);
82 assert (buf->size == 0);
83 assert_ptr_not_null (buf->ffree);
84 assert_ptr_not_null (buf->frealloc);
85
86 p11_rpc_buffer_free (buf);
87 }
88
89 static void
test_uint16(void)90 test_uint16 (void)
91 {
92 p11_buffer buffer;
93 uint16_t val = UINT16_MAX;
94 size_t next;
95 bool ret;
96
97 p11_buffer_init (&buffer, 0);
98
99 next = 0;
100 ret = p11_rpc_buffer_get_uint16 (&buffer, &next, &val);
101 assert_num_eq (false, ret);
102 assert_num_eq (0, next);
103 assert_num_eq (UINT16_MAX, val);
104
105 p11_buffer_reset (&buffer, 0);
106
107 ret = p11_rpc_buffer_set_uint16 (&buffer, 0, 0x6789);
108 assert_num_eq (false, ret);
109
110 p11_buffer_reset (&buffer, 0);
111
112 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
113
114 p11_rpc_buffer_add_uint16 (&buffer, 0x6789);
115 assert_num_eq (9, buffer.len);
116 assert (!p11_buffer_failed (&buffer));
117
118 next = 7;
119 ret = p11_rpc_buffer_get_uint16 (&buffer, &next, &val);
120 assert_num_eq (true, ret);
121 assert_num_eq (9, next);
122 assert_num_eq (0x6789, val);
123
124 p11_buffer_uninit (&buffer);
125 }
126
127 static void
test_uint16_static(void)128 test_uint16_static (void)
129 {
130 p11_buffer buf = { (unsigned char *)"pad0\x67\x89", 6, };
131 uint16_t val = UINT16_MAX;
132 size_t next;
133 bool ret;
134
135 next = 4;
136 ret = p11_rpc_buffer_get_uint16 (&buf, &next, &val);
137 assert_num_eq (true, ret);
138 assert_num_eq (6, next);
139 assert_num_eq (0x6789, val);
140 }
141
142 static void
test_uint32(void)143 test_uint32 (void)
144 {
145 p11_buffer buffer;
146 uint32_t val = UINT32_MAX;
147 size_t next;
148 bool ret;
149
150 p11_buffer_init (&buffer, 0);
151
152 next = 0;
153 ret = p11_rpc_buffer_get_uint32 (&buffer, &next, &val);
154 assert_num_eq (false, ret);
155 assert_num_eq (0, next);
156 assert_num_eq (UINT32_MAX, val);
157
158 p11_buffer_reset (&buffer, 0);
159
160 ret = p11_rpc_buffer_set_uint32 (&buffer, 0, 0x12345678);
161 assert_num_eq (false, ret);
162
163 p11_buffer_reset (&buffer, 0);
164
165 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
166
167 p11_rpc_buffer_add_uint32 (&buffer, 0x12345678);
168 assert_num_eq (11, buffer.len);
169 assert (!p11_buffer_failed (&buffer));
170
171 next = 7;
172 ret = p11_rpc_buffer_get_uint32 (&buffer, &next, &val);
173 assert_num_eq (true, ret);
174 assert_num_eq (11, next);
175 assert_num_eq (0x12345678, val);
176
177 p11_buffer_uninit (&buffer);
178 }
179
180 static void
test_uint32_static(void)181 test_uint32_static (void)
182 {
183 p11_buffer buf = { (unsigned char *)"pad0\x23\x45\x67\x89", 8, };
184 uint32_t val = UINT32_MAX;
185 size_t next;
186 bool ret;
187
188 next = 4;
189 ret = p11_rpc_buffer_get_uint32 (&buf, &next, &val);
190 assert_num_eq (true, ret);
191 assert_num_eq (8, next);
192 assert_num_eq (0x23456789, val);
193 }
194
195 static void
test_uint64(void)196 test_uint64 (void)
197 {
198 p11_buffer buffer;
199 uint64_t val = UINT64_MAX;
200 size_t next;
201 bool ret;
202
203 p11_buffer_init (&buffer, 0);
204
205 next = 0;
206 ret = p11_rpc_buffer_get_uint64 (&buffer, &next, &val);
207 assert_num_eq (0, ret);
208 assert_num_eq (0, next);
209 assert (UINT64_MAX == val);
210
211 p11_buffer_reset (&buffer, 0);
212
213 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
214
215 p11_rpc_buffer_add_uint64 (&buffer, 0x0123456708ABCDEFull);
216 assert_num_eq (15, buffer.len);
217 assert (!p11_buffer_failed (&buffer));
218
219 next = 7;
220 ret = p11_rpc_buffer_get_uint64 (&buffer, &next, &val);
221 assert_num_eq (true, ret);
222 assert_num_eq (15, next);
223 assert (0x0123456708ABCDEFull == val);
224
225 p11_buffer_uninit (&buffer);
226 }
227
228 static void
test_uint64_static(void)229 test_uint64_static (void)
230 {
231 p11_buffer buf = { (unsigned char *)"pad0\x89\x67\x45\x23\x11\x22\x33\x44", 12, };
232 uint64_t val = UINT64_MAX;
233 size_t next;
234 bool ret;
235
236 next = 4;
237 ret = p11_rpc_buffer_get_uint64 (&buf, &next, &val);
238 assert_num_eq (true, ret);
239 assert_num_eq (12, next);
240 assert (0x8967452311223344ull == val);
241 }
242
243 static void
test_byte_array(void)244 test_byte_array (void)
245 {
246 p11_buffer buffer;
247 unsigned char bytes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
248 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
249 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
250 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
251
252 const unsigned char *val;
253 size_t length = ~0;
254 size_t next;
255 bool ret;
256
257 p11_buffer_init (&buffer, 0);
258
259 /* Invalid read */
260
261 next = 0;
262 ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length);
263 assert_num_eq (false, ret);
264 assert_num_eq (0, next);
265 assert_num_eq (~0, length);
266
267 /* Test full array */
268
269 p11_buffer_reset (&buffer, 0);
270 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
271
272 p11_rpc_buffer_add_byte_array (&buffer, bytes, 32);
273 assert_num_eq (43, buffer.len);
274 assert (!p11_buffer_failed (&buffer));
275
276 next = 7;
277 ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length);
278 assert_num_eq (true, ret);
279 assert_num_eq (43, next);
280 assert_num_eq (32, length);
281 assert (memcmp (val, bytes, 32) == 0);
282
283 p11_buffer_uninit (&buffer);
284 }
285
286 static void
test_byte_array_null(void)287 test_byte_array_null (void)
288 {
289 p11_buffer buffer;
290 const unsigned char *val;
291 size_t length = ~0;
292 size_t next;
293 bool ret;
294
295 p11_buffer_init (&buffer, 0);
296
297 p11_buffer_reset (&buffer, 0);
298 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
299
300 p11_rpc_buffer_add_byte_array (&buffer, NULL, 0);
301 assert_num_eq (11, buffer.len);
302 assert (!p11_buffer_failed (&buffer));
303
304 next = 7;
305 ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length);
306 assert_num_eq (true, ret);
307 assert_num_eq (11, next);
308 assert_num_eq (0, length);
309 assert_ptr_eq (NULL, (void*)val);
310
311 p11_buffer_uninit (&buffer);
312 }
313
314 static void
test_byte_array_too_long(void)315 test_byte_array_too_long (void)
316 {
317 p11_buffer buffer;
318 const unsigned char *val = NULL;
319 size_t length = ~0;
320 size_t next;
321 bool ret;
322
323 p11_buffer_init (&buffer, 0);
324
325 p11_buffer_reset (&buffer, 0);
326 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
327 assert (!p11_buffer_failed (&buffer));
328
329 /* Passing a too short buffer here shouldn't matter, as length is checked for sanity */
330 p11_rpc_buffer_add_byte_array (&buffer, (unsigned char *)"", 0x9fffffff);
331 assert (p11_buffer_failed (&buffer));
332
333 /* Force write a too long byte arary to buffer */
334 p11_buffer_reset (&buffer, 0);
335 p11_rpc_buffer_add_uint32 (&buffer, 0x9fffffff);
336
337 next = 0;
338 ret = p11_rpc_buffer_get_byte_array (&buffer, &next, &val, &length);
339 assert_num_eq (false, ret);
340 assert_num_eq (0, next);
341 assert_num_eq (~0, length);
342 assert_ptr_eq (NULL, (void*)val);
343
344 p11_buffer_uninit (&buffer);
345 }
346
347 static void
test_byte_array_static(void)348 test_byte_array_static (void)
349 {
350 unsigned char data[] = { 'p', 'a', 'd', 0x00, 0x00, 0x00, 0x00, 0x20,
351 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
352 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
353 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
354 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
355 p11_buffer buf = { data, 0x40, };
356 const unsigned char *val;
357 size_t length = ~0;
358 size_t next;
359 bool ret;
360
361 next = 4;
362 ret = p11_rpc_buffer_get_byte_array (&buf, &next, &val, &length);
363 assert_num_eq (true, ret);
364 assert_num_eq (40, next);
365 assert_num_eq (32, length);
366 assert (memcmp (data + 8, val, 32) == 0);
367 }
368
369 static void
test_byte_value(void)370 test_byte_value (void)
371 {
372 p11_buffer buffer;
373 unsigned char bytes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
374 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
375 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
376 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
377
378 char val[16];
379 size_t offset = 0;
380 CK_ULONG val_size;
381 bool ret;
382
383 p11_buffer_init (&buffer, 0);
384
385 p11_rpc_buffer_add_byte_value (&buffer, bytes, sizeof(bytes));
386 assert (p11_buffer_failed (&buffer));
387
388 p11_buffer_reset (&buffer, 0);
389
390 p11_rpc_buffer_add_byte_value (&buffer, bytes, 1);
391 assert (!p11_buffer_failed (&buffer));
392
393 ret = p11_rpc_buffer_get_byte_value (&buffer, &offset, val, &val_size);
394 assert_num_eq (true, ret);
395
396 assert_num_eq (bytes[0], val[0]);
397
398 /* Read out of bound */
399 ret = p11_rpc_buffer_get_byte_value (&buffer, &offset, val, &val_size);
400 assert_num_eq (false, ret);
401
402 p11_buffer_uninit (&buffer);
403 }
404
405 static void
test_ulong_value(void)406 test_ulong_value (void)
407 {
408 p11_buffer buffer;
409 p11_buffer buf = { (unsigned char *)"pad0\x00\x00\x00\x00\x23\x45\x67\x89", 12, };
410 CK_ULONG val = ULONG_MAX;
411 size_t offset = 0;
412 CK_ULONG val_size;
413 bool ret;
414
415 offset = 4;
416 ret = p11_rpc_buffer_get_ulong_value (&buf, &offset, &val, &val_size);
417 assert_num_eq (true, ret);
418 assert_num_eq (12, offset);
419 assert_num_eq (sizeof(val), val_size);
420 assert_num_eq (0x23456789, val);
421
422 p11_buffer_init (&buffer, 0);
423
424 val = ULONG_MAX;
425 offset = 0;
426 val_size = SIZEOF_UNSIGNED_LONG;
427 ret = p11_rpc_buffer_get_ulong_value (&buffer, &offset, &val, &val_size);
428 assert_num_eq (0, ret);
429 assert_num_eq (0, offset);
430 assert_num_eq (SIZEOF_UNSIGNED_LONG, val_size);
431 assert_num_eq (ULONG_MAX, val);
432
433 p11_buffer_reset (&buffer, 0);
434
435 p11_buffer_add (&buffer, (unsigned char *)"padding", 7);
436
437 val = ULONG_VAL;
438 p11_rpc_buffer_add_ulong_value (&buffer, &val, SIZEOF_UNSIGNED_LONG);
439 assert (!p11_buffer_failed (&buffer));
440 /* The value is always stored as 64-bit integer */
441 assert_num_eq (7 + 8, buffer.len);
442
443 val = ULONG_MAX;
444 offset = 7;
445 ret = p11_rpc_buffer_get_ulong_value (&buffer, &offset, &val, &val_size);
446 assert_num_eq (true, ret);
447 /* The value is always stored as 64-bit integer */
448 assert_num_eq (7 + 8, offset);
449 assert_num_eq (ULONG_VAL, *(CK_ULONG *)&val);
450
451 /* Read out of bound */
452 val = ULONG_MAX;
453 ret = p11_rpc_buffer_get_ulong_value (&buffer, &offset, &val, &val_size);
454 assert_num_eq (false, ret);
455
456 p11_buffer_uninit (&buffer);
457 }
458
459 static void
test_attribute_array_value(void)460 test_attribute_array_value (void)
461 {
462 p11_buffer buffer;
463 CK_BBOOL truev = CK_TRUE;
464 char labelv[] = "label";
465 CK_ATTRIBUTE attrs[] = {
466 { CKA_MODIFIABLE, &truev, sizeof (truev) },
467 { CKA_LABEL, labelv, sizeof (labelv) }
468 };
469 CK_BBOOL boolv = CK_FALSE;
470 char strv[] = "\0\0\0\0\0";
471 CK_ATTRIBUTE val[] = {
472 { CKA_MODIFIABLE, &boolv, sizeof (boolv) },
473 { CKA_LABEL, strv, sizeof (strv) }
474 };
475 CK_ULONG val_size;
476 size_t offset = 0, offset2;
477 bool ret;
478
479 p11_buffer_init (&buffer, 0);
480
481 p11_rpc_buffer_add_attribute_array_value(&buffer, attrs, sizeof(attrs));
482 assert (!p11_buffer_failed (&buffer));
483
484 offset2 = offset;
485 ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, NULL, &val_size);
486 assert_num_eq (true, ret);
487
488 offset = offset2;
489 ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, val, &val_size);
490 assert_num_eq (true, ret);
491 assert_num_eq (val[0].type, CKA_MODIFIABLE);
492 assert_num_eq (*(CK_BBOOL *)val[0].pValue, CK_TRUE);
493 assert_num_eq (val[0].ulValueLen, sizeof (truev));
494 assert_num_eq (val[1].type, CKA_LABEL);
495 assert_str_eq (val[1].pValue, "label");
496 assert_num_eq (val[1].ulValueLen, sizeof (labelv));
497
498 p11_buffer_uninit (&buffer);
499 }
500
501 static void
test_mechanism_type_array_value(void)502 test_mechanism_type_array_value (void)
503 {
504 p11_buffer buffer;
505 CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_DSA, CKM_SHA256_RSA_PKCS };
506 CK_MECHANISM_TYPE val[3];
507 CK_ULONG val_size;
508 size_t offset = 0, offset2;
509 bool ret;
510
511 p11_buffer_init (&buffer, 0);
512
513 p11_rpc_buffer_add_mechanism_type_array_value(&buffer, mechs, sizeof(mechs));
514 assert (!p11_buffer_failed (&buffer));
515
516 offset2 = offset;
517 ret = p11_rpc_buffer_get_mechanism_type_array_value(&buffer, &offset, NULL, &val_size);
518 assert_num_eq (true, ret);
519
520 offset = offset2;
521 ret = p11_rpc_buffer_get_mechanism_type_array_value(&buffer, &offset, val, &val_size);
522 assert_num_eq (true, ret);
523 assert_num_eq (val[0], CKM_RSA_PKCS);
524 assert_num_eq (val[1], CKM_DSA);
525 assert_num_eq (val[2], CKM_SHA256_RSA_PKCS);
526
527 p11_buffer_uninit (&buffer);
528 }
529
530 static void
test_date_value(void)531 test_date_value (void)
532 {
533 p11_buffer buffer;
534 CK_DATE date, val;
535 size_t offset = 0;
536 CK_ULONG val_size;
537 bool ret;
538
539 memcpy (date.year, "2017", 4);
540 memcpy (date.month, "05", 2);
541 memcpy (date.day, "16", 2);
542
543 p11_buffer_init (&buffer, 0);
544
545 p11_rpc_buffer_add_date_value(&buffer, &date, sizeof(date));
546 assert (!p11_buffer_failed (&buffer));
547
548 ret = p11_rpc_buffer_get_date_value(&buffer, &offset, &val, &val_size);
549 assert_num_eq (true, ret);
550
551 assert (memcmp (val.year, date.year, 4) == 0);
552 assert (memcmp (val.month, date.month, 2) == 0);
553 assert (memcmp (val.day, date.day, 2) == 0);
554
555 p11_buffer_uninit (&buffer);
556 }
557
558 static void
test_date_value_empty(void)559 test_date_value_empty (void)
560 {
561 p11_buffer buffer;
562 CK_DATE val;
563 size_t offset = 0;
564 CK_ULONG val_size;
565 bool ret;
566
567 p11_buffer_init (&buffer, 0);
568
569 p11_rpc_buffer_add_date_value(&buffer, NULL, 0);
570 assert (!p11_buffer_failed (&buffer));
571
572 ret = p11_rpc_buffer_get_date_value(&buffer, &offset, &val, &val_size);
573 assert_num_eq (true, ret);
574
575 assert_num_eq (0, val_size);
576
577 p11_buffer_uninit (&buffer);
578 }
579
580 static void
test_byte_array_value(void)581 test_byte_array_value (void)
582 {
583 p11_buffer buffer;
584 unsigned char bytes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
585 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
586 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
587 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
588
589 unsigned char val[32];
590 size_t offset = 0;
591 CK_ULONG val_size;
592 bool ret;
593
594 p11_buffer_init (&buffer, 0);
595
596 p11_rpc_buffer_add_byte_array_value(&buffer, bytes, sizeof(bytes));
597 assert (!p11_buffer_failed (&buffer));
598
599 ret = p11_rpc_buffer_get_byte_array_value(&buffer, &offset, val, &val_size);
600 assert_num_eq (true, ret);
601
602 assert_num_eq (bytes[0], val[0]);
603
604 p11_buffer_uninit (&buffer);
605 }
606
607 static void
test_mechanism_value(void)608 test_mechanism_value (void)
609 {
610 p11_buffer buffer;
611 CK_MECHANISM_TYPE *mechanisms;
612 CK_RSA_PKCS_PSS_PARAMS pss_params = {
613 CKM_SHA256,
614 CKG_MGF1_SHA256,
615 32
616 };
617 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
618 CKM_SHA384,
619 CKG_MGF1_SHA384,
620 0,
621 NULL,
622 0
623 };
624 CK_MECHANISM mechs[] = {
625 { CKM_RSA_PKCS_PSS, &pss_params, sizeof (pss_params) },
626 { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof (oaep_params) }
627 };
628
629 CK_MECHANISM val;
630 size_t offset = 0;
631 bool ret;
632 size_t i;
633
634 mechanisms = p11_rpc_mechanisms_override_supported;
635 p11_rpc_mechanisms_override_supported = NULL;
636
637 p11_buffer_init (&buffer, 0);
638
639 for (i = 0; i < ELEMS (mechs); i++) {
640 size_t offset2 = offset;
641
642 p11_rpc_buffer_add_mechanism (&buffer, &mechs[i]);
643 assert (!p11_buffer_failed (&buffer));
644
645 memset (&val, 0, sizeof (val));
646 ret = p11_rpc_buffer_get_mechanism (&buffer, &offset, &val);
647 assert_num_eq (true, ret);
648 assert_num_eq (mechs[i].mechanism, val.mechanism);
649 assert_ptr_eq (NULL, val.pParameter);
650 assert_num_eq (mechs[i].ulParameterLen, val.ulParameterLen);
651
652 val.pParameter = malloc (val.ulParameterLen);
653 assert_ptr_not_null (val.pParameter);
654
655 offset = offset2;
656 ret = p11_rpc_buffer_get_mechanism (&buffer, &offset, &val);
657 assert_num_eq (true, ret);
658 assert_num_eq (mechs[i].mechanism, val.mechanism);
659 assert_num_eq (mechs[i].ulParameterLen, val.ulParameterLen);
660 assert (memcmp (val.pParameter, mechs[i].pParameter, val.ulParameterLen) == 0);
661
662 free (val.pParameter);
663 }
664
665 p11_buffer_uninit (&buffer);
666
667 p11_rpc_mechanisms_override_supported = mechanisms;
668 }
669
670 static void
test_message_write(void)671 test_message_write (void)
672 {
673 p11_rpc_message msg;
674 p11_buffer buffer;
675 CK_BBOOL truev = CK_TRUE;
676 CK_ULONG zerov = (CK_ULONG)0;
677 char labelv[] = "label";
678 CK_ATTRIBUTE attrs[] = {
679 { CKA_MODIFIABLE, &truev, sizeof (truev) },
680 { CKA_LABEL, labelv, sizeof (labelv) },
681 /* These are cases when C_GetAttributeValue is called
682 * to obtain the length */
683 { CKA_COPYABLE, NULL, sizeof (truev) },
684 { CKA_BITS_PER_PIXEL, NULL, sizeof (zerov) }
685 };
686 bool ret;
687
688 ret = p11_buffer_init (&buffer, 0);
689 assert_num_eq (true, ret);
690 p11_rpc_message_init (&msg, &buffer, &buffer);
691 ret = p11_rpc_message_write_attribute_array (&msg, attrs, ELEMS(attrs));
692 assert_num_eq (true, ret);
693 p11_rpc_message_clear (&msg);
694 p11_buffer_uninit (&buffer);
695 }
696
697 static p11_virtual base;
698 static unsigned int rpc_initialized = 0;
699
700 static CK_RV
rpc_initialize(p11_rpc_client_vtable * vtable,void * init_reserved)701 rpc_initialize (p11_rpc_client_vtable *vtable,
702 void *init_reserved)
703 {
704 assert_str_eq (vtable->data, "vtable-data");
705 assert_num_cmp (p11_forkid, !=, rpc_initialized);
706 rpc_initialized = p11_forkid;
707
708 return CKR_OK;
709 }
710
711 static CK_RV
rpc_initialize_fails(p11_rpc_client_vtable * vtable,void * init_reserved)712 rpc_initialize_fails (p11_rpc_client_vtable *vtable,
713 void *init_reserved)
714 {
715 assert_str_eq (vtable->data, "vtable-data");
716 assert_num_cmp (p11_forkid, !=, rpc_initialized);
717 return CKR_FUNCTION_FAILED;
718 }
719
720 static CK_RV
rpc_initialize_device_removed(p11_rpc_client_vtable * vtable,void * init_reserved)721 rpc_initialize_device_removed (p11_rpc_client_vtable *vtable,
722 void *init_reserved)
723 {
724 assert_str_eq (vtable->data, "vtable-data");
725 assert_num_cmp (p11_forkid, !=, rpc_initialized);
726 return CKR_DEVICE_REMOVED;
727 }
728
729 static CK_RV
rpc_transport(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)730 rpc_transport (p11_rpc_client_vtable *vtable,
731 p11_buffer *request,
732 p11_buffer *response)
733 {
734 bool ret;
735
736 assert_str_eq (vtable->data, "vtable-data");
737
738 /* Just pass directly to the server code */
739 ret = p11_rpc_server_handle (&base.funcs, request, response);
740 assert (ret == true);
741
742 return CKR_OK;
743 }
744
745 static void
rpc_finalize(p11_rpc_client_vtable * vtable,void * fini_reserved)746 rpc_finalize (p11_rpc_client_vtable *vtable,
747 void *fini_reserved)
748 {
749 assert_str_eq (vtable->data, "vtable-data");
750 assert_num_cmp (p11_forkid, ==, rpc_initialized);
751 rpc_initialized = 0;
752 }
753
754 static void
test_initialize(void)755 test_initialize (void)
756 {
757 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize };
758 p11_virtual mixin;
759 bool ret;
760 CK_RV rv;
761
762 /* Build up our own function list */
763 rpc_initialized = 0;
764 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
765
766 ret = p11_rpc_client_init (&mixin, &vtable);
767 assert_num_eq (true, ret);
768
769 rv = mixin.funcs.C_Initialize (&mixin.funcs, NULL);
770 assert (rv == CKR_OK);
771 assert_num_eq (p11_forkid, rpc_initialized);
772
773 rv = mixin.funcs.C_Finalize (&mixin.funcs, NULL);
774 assert (rv == CKR_OK);
775 assert_num_cmp (p11_forkid, !=, rpc_initialized);
776
777 p11_virtual_uninit (&mixin);
778 }
779
780 static void
test_not_initialized(void)781 test_not_initialized (void)
782 {
783 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize };
784 p11_virtual mixin;
785 CK_INFO info;
786 bool ret;
787 CK_RV rv;
788
789 /* Build up our own function list */
790 rpc_initialized = 0;
791 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
792
793 ret = p11_rpc_client_init (&mixin, &vtable);
794 assert_num_eq (true, ret);
795
796 rv = (mixin.funcs.C_GetInfo) (&mixin.funcs, &info);
797 assert (rv == CKR_CRYPTOKI_NOT_INITIALIZED);
798
799 p11_virtual_uninit (&mixin);
800 }
801
802 static void
test_initialize_fails_on_client(void)803 test_initialize_fails_on_client (void)
804 {
805 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize_fails, rpc_transport, rpc_finalize };
806 p11_virtual mixin;
807 bool ret;
808 CK_RV rv;
809
810 /* Build up our own function list */
811 rpc_initialized = 0;
812 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
813
814 ret = p11_rpc_client_init (&mixin, &vtable);
815 assert_num_eq (true, ret);
816
817 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
818 assert (rv == CKR_FUNCTION_FAILED);
819 assert_num_eq (0, rpc_initialized);
820
821 p11_virtual_uninit (&mixin);
822 }
823
824 static CK_RV
rpc_transport_fails(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)825 rpc_transport_fails (p11_rpc_client_vtable *vtable,
826 p11_buffer *request,
827 p11_buffer *response)
828 {
829 return CKR_FUNCTION_REJECTED;
830 }
831
832 static void
test_transport_fails(void)833 test_transport_fails (void)
834 {
835 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_fails, rpc_finalize };
836 p11_virtual mixin;
837 bool ret;
838 CK_RV rv;
839
840 /* Build up our own function list */
841 rpc_initialized = 0;
842 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
843
844 ret = p11_rpc_client_init (&mixin, &vtable);
845 assert_num_eq (true, ret);
846
847 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
848 assert (rv == CKR_FUNCTION_REJECTED);
849 assert_num_eq (0, rpc_initialized);
850
851 p11_virtual_uninit (&mixin);
852 }
853
854 static void
test_initialize_fails_on_server(void)855 test_initialize_fails_on_server (void)
856 {
857 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport, rpc_finalize };
858 p11_virtual mixin;
859 bool ret;
860 CK_RV rv;
861
862 /* Build up our own function list */
863 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
864 base.funcs.C_Initialize = mock_X_Initialize__fails;
865
866 ret = p11_rpc_client_init (&mixin, &vtable);
867 assert_num_eq (true, ret);
868
869 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
870 assert (rv == CKR_FUNCTION_FAILED);
871 assert_num_eq (0, rpc_initialized);
872
873 p11_virtual_uninit (&mixin);
874 }
875
876 static CK_RV
rpc_transport_bad_parse(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)877 rpc_transport_bad_parse (p11_rpc_client_vtable *vtable,
878 p11_buffer *request,
879 p11_buffer *response)
880 {
881 int rc;
882
883 assert_str_eq (vtable->data, "vtable-data");
884
885 /* Just zero bytes is an invalid message */
886 rc = p11_buffer_reset (response, 2);
887 assert (rc >= 0);
888
889 memset (response->data, 0, 2);
890 response->len = 2;
891 return CKR_OK;
892 }
893
894 static void
test_transport_bad_parse(void)895 test_transport_bad_parse (void)
896 {
897 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_bad_parse, rpc_finalize };
898 p11_virtual mixin;
899 bool ret;
900 CK_RV rv;
901
902 /* Build up our own function list */
903 rpc_initialized = 0;
904 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
905
906 ret = p11_rpc_client_init (&mixin, &vtable);
907 assert_num_eq (true, ret);
908
909 p11_kit_be_quiet ();
910
911 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
912 assert (rv == CKR_DEVICE_ERROR);
913 assert_num_eq (0, rpc_initialized);
914
915 p11_message_loud ();
916 p11_virtual_uninit (&mixin);
917 }
918
919 static CK_RV
rpc_transport_short_error(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)920 rpc_transport_short_error (p11_rpc_client_vtable *vtable,
921 p11_buffer *request,
922 p11_buffer *response)
923 {
924 int rc;
925
926 unsigned char data[] = {
927 0x00, 0x00, 0x00, 0x00, /* RPC_CALL_ERROR */
928 0x00, 0x00, 0x00, 0x01, 0x75, /* signature 'u' */
929 0x00, 0x01, /* short error */
930 };
931
932 assert_str_eq (vtable->data, "vtable-data");
933
934 rc = p11_buffer_reset (response, sizeof (data));
935 assert (rc >= 0);
936
937 memcpy (response->data, data, sizeof (data));
938 response->len = sizeof (data);
939 return CKR_OK;
940 }
941
942 static void
test_transport_short_error(void)943 test_transport_short_error (void)
944 {
945 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_short_error, rpc_finalize };
946 p11_virtual mixin;
947 bool ret;
948 CK_RV rv;
949
950 /* Build up our own function list */
951 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
952
953 ret = p11_rpc_client_init (&mixin, &vtable);
954 assert_num_eq (true, ret);
955
956 p11_kit_be_quiet ();
957
958 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
959 assert (rv == CKR_DEVICE_ERROR);
960 assert_num_eq (0, rpc_initialized);
961
962 p11_message_loud ();
963 p11_virtual_uninit (&mixin);
964 }
965
966 static CK_RV
rpc_transport_invalid_error(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)967 rpc_transport_invalid_error (p11_rpc_client_vtable *vtable,
968 p11_buffer *request,
969 p11_buffer *response)
970 {
971 int rc;
972
973 unsigned char data[] = {
974 0x00, 0x00, 0x00, 0x00, /* RPC_CALL_ERROR */
975 0x00, 0x00, 0x00, 0x01, 0x75, /* signature 'u' */
976 0x00, 0x00, 0x00, 0x00, /* a CKR_OK error*/
977 0x00, 0x00, 0x00, 0x00,
978 };
979
980 assert_str_eq (vtable->data, "vtable-data");
981
982 rc = p11_buffer_reset (response, sizeof (data));
983 assert (rc >= 0);
984 memcpy (response->data, data, sizeof (data));
985 response->len = sizeof (data);
986 return CKR_OK;
987 }
988
989 static void
test_transport_invalid_error(void)990 test_transport_invalid_error (void)
991 {
992 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_invalid_error, rpc_finalize };
993 p11_virtual mixin;
994 bool ret;
995 CK_RV rv;
996
997 /* Build up our own function list */
998 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
999
1000 ret = p11_rpc_client_init (&mixin, &vtable);
1001 assert_num_eq (true, ret);
1002
1003 p11_kit_be_quiet ();
1004
1005 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
1006 assert (rv == CKR_DEVICE_ERROR);
1007 assert_num_eq (0, rpc_initialized);
1008
1009 p11_message_loud ();
1010 p11_virtual_uninit (&mixin);
1011 }
1012
1013 static CK_RV
rpc_transport_wrong_response(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)1014 rpc_transport_wrong_response (p11_rpc_client_vtable *vtable,
1015 p11_buffer *request,
1016 p11_buffer *response)
1017 {
1018 int rc;
1019
1020 unsigned char data[] = {
1021 0x00, 0x00, 0x00, 0x02, /* RPC_CALL_C_Finalize */
1022 0x00, 0x00, 0x00, 0x00, /* signature '' */
1023 };
1024
1025 assert_str_eq (vtable->data, "vtable-data");
1026
1027 rc = p11_buffer_reset (response, sizeof (data));
1028 assert (rc >= 0);
1029 memcpy (response->data, data, sizeof (data));
1030 response->len = sizeof (data);
1031 return CKR_OK;
1032 }
1033
1034 static void
test_transport_wrong_response(void)1035 test_transport_wrong_response (void)
1036 {
1037 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_wrong_response, rpc_finalize };
1038 p11_virtual mixin;
1039 bool ret;
1040 CK_RV rv;
1041
1042 /* Build up our own function list */
1043 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
1044
1045 ret = p11_rpc_client_init (&mixin, &vtable);
1046 assert_num_eq (true, ret);
1047
1048 p11_kit_be_quiet ();
1049
1050 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
1051 assert (rv == CKR_DEVICE_ERROR);
1052 assert_num_eq (0, rpc_initialized);
1053
1054 p11_message_loud ();
1055 p11_virtual_uninit (&mixin);
1056 }
1057
1058 static CK_RV
rpc_transport_bad_contents(p11_rpc_client_vtable * vtable,p11_buffer * request,p11_buffer * response)1059 rpc_transport_bad_contents (p11_rpc_client_vtable *vtable,
1060 p11_buffer *request,
1061 p11_buffer *response)
1062 {
1063 int rc;
1064
1065 unsigned char data[] = {
1066 0x00, 0x00, 0x00, 0x02, /* RPC_CALL_C_GetInfo */
1067 0x00, 0x00, 0x00, 0x05, /* signature 'vsusv' */
1068 'v', 's', 'u', 's', 'v',
1069 0x00, 0x00, 0x00, 0x00, /* invalid data */
1070 };
1071
1072 assert_str_eq (vtable->data, "vtable-data");
1073
1074 rc = p11_buffer_reset (response, sizeof (data));
1075 assert (rc >= 0);
1076 memcpy (response->data, data, sizeof (data));
1077 response->len = sizeof (data);
1078 return CKR_OK;
1079 }
1080
1081 static void
test_transport_bad_contents(void)1082 test_transport_bad_contents (void)
1083 {
1084 p11_rpc_client_vtable vtable = { "vtable-data", rpc_initialize, rpc_transport_bad_contents, rpc_finalize };
1085 p11_virtual mixin;
1086 bool ret;
1087 CK_RV rv;
1088
1089 /* Build up our own function list */
1090 p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL);
1091
1092 ret = p11_rpc_client_init (&mixin, &vtable);
1093 assert_num_eq (true, ret);
1094
1095 p11_kit_be_quiet ();
1096
1097 rv = (mixin.funcs.C_Initialize) (&mixin.funcs, NULL);
1098 assert (rv == CKR_DEVICE_ERROR);
1099 assert_num_eq (0, rpc_initialized);
1100
1101 p11_message_loud ();
1102 p11_virtual_uninit (&mixin);
1103 }
1104
1105 static p11_rpc_client_vtable test_normal_vtable = {
1106 NULL,
1107 rpc_initialize,
1108 rpc_transport,
1109 rpc_finalize,
1110 };
1111
1112 static p11_rpc_client_vtable test_device_removed_vtable = {
1113 NULL,
1114 rpc_initialize_device_removed,
1115 rpc_transport,
1116 rpc_finalize,
1117 };
1118
1119 static void
mixin_free(void * data)1120 mixin_free (void *data)
1121 {
1122 p11_virtual *mixin = data;
1123 p11_virtual_uninit (mixin);
1124 free (mixin);
1125 }
1126
1127 static CK_FUNCTION_LIST_PTR
setup_test_rpc_module(p11_rpc_client_vtable * vtable,CK_FUNCTION_LIST * module_template,CK_SESSION_HANDLE * session)1128 setup_test_rpc_module (p11_rpc_client_vtable *vtable,
1129 CK_FUNCTION_LIST *module_template,
1130 CK_SESSION_HANDLE *session)
1131 {
1132 CK_FUNCTION_LIST *rpc_module;
1133 p11_virtual *mixin;
1134 CK_RV rv;
1135
1136 /* Build up our own function list */
1137 p11_virtual_init (&base, &p11_virtual_base, module_template, NULL);
1138
1139 mixin = calloc (1, sizeof (p11_virtual));
1140 assert (mixin != NULL);
1141
1142 vtable->data = "vtable-data";
1143 if (!p11_rpc_client_init (mixin, vtable))
1144 assert_not_reached ();
1145
1146 rpc_module = p11_virtual_wrap (mixin, mixin_free);
1147 assert_ptr_not_null (rpc_module);
1148
1149 rv = p11_kit_module_initialize (rpc_module);
1150 assert (rv == CKR_OK);
1151
1152 if (session) {
1153 rv = (rpc_module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_RW_SESSION | CKF_SERIAL_SESSION,
1154 NULL, NULL, session);
1155 assert (rv == CKR_OK);
1156 }
1157
1158 return rpc_module;
1159 }
1160
1161 static CK_FUNCTION_LIST *
setup_mock_module(CK_SESSION_HANDLE * session)1162 setup_mock_module (CK_SESSION_HANDLE *session)
1163 {
1164 return setup_test_rpc_module (&test_normal_vtable, &mock_module, session);
1165 }
1166
1167 static void
teardown_mock_module(CK_FUNCTION_LIST * rpc_module)1168 teardown_mock_module (CK_FUNCTION_LIST *rpc_module)
1169 {
1170 p11_kit_module_finalize (rpc_module);
1171 p11_virtual_unwrap (rpc_module);
1172 }
1173
1174 static void
test_get_info_stand_in(void)1175 test_get_info_stand_in (void)
1176 {
1177 CK_FUNCTION_LIST_PTR rpc_module;
1178 CK_INFO info;
1179 CK_RV rv;
1180 char *string;
1181
1182 rpc_module = setup_test_rpc_module (&test_device_removed_vtable,
1183 &mock_module_no_slots, NULL);
1184
1185 rv = (rpc_module->C_GetInfo) (&info);
1186 assert (rv == CKR_OK);
1187
1188 assert_num_eq (CRYPTOKI_VERSION_MAJOR, info.cryptokiVersion.major);
1189 assert_num_eq (CRYPTOKI_VERSION_MINOR, info.cryptokiVersion.minor);
1190 string = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID));
1191 assert_str_eq ("p11-kit", string);
1192 free (string);
1193 string = p11_kit_space_strdup (info.libraryDescription, sizeof (info.libraryDescription));
1194 assert_str_eq ("p11-kit (no connection)", string);
1195 free (string);
1196 assert_num_eq (0, info.flags);
1197 assert_num_eq (1, info.libraryVersion.major);
1198 assert_num_eq (1, info.libraryVersion.minor);
1199
1200 teardown_mock_module (rpc_module);
1201 }
1202
1203 static void
test_get_slot_list_no_device(void)1204 test_get_slot_list_no_device (void)
1205 {
1206 CK_FUNCTION_LIST_PTR rpc_module;
1207 CK_SLOT_ID slot_list[8];
1208 CK_ULONG count;
1209 CK_RV rv;
1210
1211 rpc_module = setup_test_rpc_module (&test_device_removed_vtable,
1212 &mock_module_no_slots, NULL);
1213
1214 rv = (rpc_module->C_GetSlotList) (CK_TRUE, NULL, &count);
1215 assert (rv == CKR_OK);
1216 assert_num_eq (0, count);
1217 rv = (rpc_module->C_GetSlotList) (CK_FALSE, NULL, &count);
1218 assert (rv == CKR_OK);
1219 assert_num_eq (0, count);
1220
1221 count = 8;
1222 rv = (rpc_module->C_GetSlotList) (CK_TRUE, slot_list, &count);
1223 assert (rv == CKR_OK);
1224 assert_num_eq (0, count);
1225
1226 count = 8;
1227 rv = (rpc_module->C_GetSlotList) (CK_FALSE, slot_list, &count);
1228 assert (rv == CKR_OK);
1229 assert_num_eq (0, count);
1230
1231 teardown_mock_module (rpc_module);
1232 }
1233
1234 static void *
invoke_in_thread(void * arg)1235 invoke_in_thread (void *arg)
1236 {
1237 CK_FUNCTION_LIST *rpc_module = arg;
1238 CK_INFO info;
1239 CK_RV rv;
1240
1241 rv = (rpc_module->C_GetInfo) (&info);
1242 assert_num_eq (rv, CKR_OK);
1243
1244 assert (memcmp (info.manufacturerID, MOCK_INFO.manufacturerID,
1245 sizeof (info.manufacturerID)) == 0);
1246
1247 return NULL;
1248 }
1249
1250 static p11_mutex_t delay_mutex;
1251
1252 static CK_RV
delayed_C_GetInfo(CK_INFO_PTR info)1253 delayed_C_GetInfo (CK_INFO_PTR info)
1254 {
1255 CK_RV rv;
1256
1257 p11_sleep_ms (rand () % 100);
1258
1259 p11_mutex_lock (&delay_mutex);
1260 rv = mock_C_GetInfo (info);
1261 p11_mutex_unlock (&delay_mutex);
1262
1263 return rv;
1264 }
1265
1266 static void
test_simultaneous_functions(void)1267 test_simultaneous_functions (void)
1268 {
1269 CK_FUNCTION_LIST real_module;
1270 CK_FUNCTION_LIST *rpc_module;
1271 const int num_threads = 128;
1272 p11_thread_t threads[num_threads];
1273 int i, ret;
1274
1275 p11_mutex_init (&delay_mutex);
1276
1277 memcpy (&real_module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
1278 real_module.C_GetInfo = delayed_C_GetInfo;
1279
1280 rpc_module = setup_test_rpc_module (&test_normal_vtable,
1281 &real_module, NULL);
1282
1283 /* Make the invoked function (above) wait */
1284 p11_mutex_lock (&delay_mutex);
1285
1286 for (i = 0; i < num_threads; i++) {
1287 ret = p11_thread_create (threads + i, invoke_in_thread, rpc_module);
1288 assert_num_eq (0, ret);
1289 }
1290
1291 /* Let the invoked functions return */
1292 p11_mutex_unlock (&delay_mutex);
1293
1294 for (i = 0; i < num_threads; i++)
1295 p11_thread_join (threads[i]);
1296
1297 teardown_mock_module (rpc_module);
1298 p11_mutex_uninit (&delay_mutex);
1299 }
1300
1301 #ifdef OS_UNIX
1302
1303 static void
test_fork_and_reinitialize(void)1304 test_fork_and_reinitialize (void)
1305 {
1306 CK_FUNCTION_LIST *rpc_module;
1307 CK_INFO info;
1308 int status;
1309 CK_RV rv;
1310 pid_t pid;
1311 int i;
1312
1313 rpc_module = setup_test_rpc_module (&test_normal_vtable,
1314 &mock_module_no_slots, NULL);
1315
1316 pid = fork ();
1317 assert_num_cmp (pid, >=, 0);
1318
1319 /* The child */
1320 if (pid == 0) {
1321 rv = (rpc_module->C_Initialize) (NULL);
1322 assert_num_eq (CKR_OK, rv);
1323
1324 for (i = 0; i < 32; i++) {
1325 rv = (rpc_module->C_GetInfo) (&info);
1326 assert_num_eq (CKR_OK, rv);
1327 }
1328
1329 rv = (rpc_module->C_Finalize) (NULL);
1330 assert_num_eq (CKR_OK, rv);
1331
1332 _exit (66);
1333 }
1334
1335 for (i = 0; i < 128; i++) {
1336 rv = (rpc_module->C_GetInfo) (&info);
1337 assert_num_eq (CKR_OK, rv);
1338 }
1339
1340 assert_num_eq (waitpid (pid, &status, 0), pid);
1341 assert_num_eq (WEXITSTATUS (status), 66);
1342
1343 teardown_mock_module (rpc_module);
1344 }
1345
1346 #endif /* OS_UNIX */
1347
1348 #include "test-mock.c"
1349
1350 int
main(int argc,char * argv[])1351 main (int argc,
1352 char *argv[])
1353 {
1354 CK_MECHANISM_TYPE mechanisms[] = {
1355 CKM_MOCK_CAPITALIZE,
1356 CKM_MOCK_PREFIX,
1357 CKM_MOCK_GENERATE,
1358 CKM_MOCK_WRAP,
1359 CKM_MOCK_DERIVE,
1360 CKM_MOCK_COUNT,
1361 0,
1362 };
1363
1364 mock_module_init ();
1365 p11_library_init ();
1366
1367 /* Override the mechanisms that the RPC mechanism will handle */
1368 p11_rpc_mechanisms_override_supported = mechanisms;
1369
1370 p11_test (test_new_free, "/rpc/new-free");
1371 p11_test (test_uint16, "/rpc/uint16");
1372 p11_test (test_uint16_static, "/rpc/uint16-static");
1373 p11_test (test_uint32, "/rpc/uint32");
1374 p11_test (test_uint32_static, "/rpc/uint32-static");
1375 p11_test (test_uint64, "/rpc/uint64");
1376 p11_test (test_uint64_static, "/rpc/uint64-static");
1377 p11_test (test_byte_array, "/rpc/byte-array");
1378 p11_test (test_byte_array_null, "/rpc/byte-array-null");
1379 p11_test (test_byte_array_too_long, "/rpc/byte-array-too-long");
1380 p11_test (test_byte_array_static, "/rpc/byte-array-static");
1381 p11_test (test_byte_value, "/rpc/byte-value");
1382 p11_test (test_ulong_value, "/rpc/ulong-value");
1383 p11_test (test_attribute_array_value, "/rpc/attribute-array-value");
1384 p11_test (test_mechanism_type_array_value, "/rpc/mechanism-type-array-value");
1385 p11_test (test_date_value, "/rpc/date-value");
1386 p11_test (test_date_value_empty, "/rpc/date-value-empty");
1387 p11_test (test_byte_array_value, "/rpc/byte-array-value");
1388 p11_test (test_mechanism_value, "/rpc/mechanism-value");
1389 p11_test (test_message_write, "/rpc/message-write");
1390
1391 p11_test (test_initialize_fails_on_client, "/rpc/initialize-fails-on-client");
1392 p11_test (test_initialize_fails_on_server, "/rpc/initialize-fails-on-server");
1393 p11_test (test_initialize, "/rpc/initialize");
1394 p11_test (test_not_initialized, "/rpc/not-initialized");
1395 p11_test (test_transport_fails, "/rpc/transport-fails");
1396 p11_test (test_transport_bad_parse, "/rpc/transport-bad-parse");
1397 p11_test (test_transport_short_error, "/rpc/transport-short-error");
1398 p11_test (test_transport_invalid_error, "/rpc/transport-invalid-error");
1399 p11_test (test_transport_wrong_response, "/rpc/transport-wrong-response");
1400 p11_test (test_transport_bad_contents, "/rpc/transport-bad-contents");
1401 p11_test (test_get_info_stand_in, "/rpc/get-info-stand-in");
1402 p11_test (test_get_slot_list_no_device, "/rpc/get-slot-list-no-device");
1403 p11_test (test_simultaneous_functions, "/rpc/simultaneous-functions");
1404
1405 #ifdef OS_UNIX
1406 p11_test (test_fork_and_reinitialize, "/rpc/fork-and-reinitialize");
1407 #endif
1408
1409 test_mock_add_tests ("/rpc");
1410
1411 return p11_test_run (argc, argv);
1412 }
1413