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