Help: Use stable 'if' namespace instead of experimental
[empathy-mirror.git] / tests / mock-pkcs11.c
bloba2ee648bbc40caab87dd06867ba9b5f50f61b5fd
1 /*
2 * Copyright (C) 2010 Stefan Walter
3 * Copyright (C) 2011 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General License as
7 * published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "config.h"
21 #include "mock-pkcs11.h"
23 #include <string.h>
26 * This is *NOT* how you'd want to implement a PKCS#11 module. This
27 * fake module simply provides enough for gnutls-pkcs11 backend to test against.
28 * It doesn't pass any tests, or behave as expected from a PKCS#11 module.
31 static gboolean initialized = FALSE;
33 typedef enum {
34 OP_FIND = 1,
35 } Operation;
37 static CK_OBJECT_HANDLE unique_identifier = 100;
38 static GHashTable *the_sessions = NULL;
39 static GHashTable *the_certificates = NULL;
40 static GHashTable *the_assertions = NULL;
42 typedef struct {
43 GcrCertificate *cert;
44 CK_ULONG assertion_type;
45 gchar *purpose;
46 gchar *peer;
47 } Assertion;
49 static void
50 free_assertion (gpointer data)
52 Assertion *assertion = data;
53 g_clear_object (&assertion->cert);
54 g_free (assertion->purpose);
55 g_free (assertion->peer);
56 g_free (assertion);
59 typedef struct {
60 CK_SESSION_HANDLE handle;
61 CK_SESSION_INFO info;
63 Operation operation;
65 /* For find operations */
66 GList *matches;
67 } Session;
69 static void
70 free_session (gpointer data)
72 Session *sess = (Session *) data;
73 g_list_free (sess->matches);
74 g_free (sess);
77 CK_OBJECT_HANDLE
78 mock_module_add_certificate (GcrCertificate *cert)
80 CK_OBJECT_HANDLE handle;
82 g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
84 handle = unique_identifier++;
85 g_hash_table_insert (the_certificates, GUINT_TO_POINTER (handle), g_object_ref (cert));
86 return handle;
89 CK_OBJECT_HANDLE
90 mock_module_add_assertion (GcrCertificate *cert,
91 CK_X_ASSERTION_TYPE assertion_type,
92 const gchar *purpose,
93 const gchar *peer)
95 Assertion *assertion;
96 CK_OBJECT_HANDLE handle;
98 g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
100 assertion = g_new0 (Assertion, 1);
101 assertion->cert = g_object_ref (cert);
102 assertion->assertion_type = assertion_type;
103 assertion->purpose = g_strdup (purpose);
104 assertion->peer = g_strdup (peer);
106 handle = unique_identifier++;
107 g_hash_table_insert (the_assertions, GUINT_TO_POINTER (handle), assertion);
108 return handle;
111 CK_RV
112 mock_C_Initialize (CK_VOID_PTR init_args)
114 CK_C_INITIALIZE_ARGS_PTR args;
116 g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
118 args = (CK_C_INITIALIZE_ARGS_PTR)init_args;
119 if (args)
121 g_return_val_if_fail (
122 (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
123 args->LockMutex == NULL && args->UnlockMutex == NULL) ||
124 (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
125 args->LockMutex != NULL && args->UnlockMutex != NULL),
126 CKR_ARGUMENTS_BAD);
128 /* Flags should allow OS locking and os threads */
129 g_return_val_if_fail ((args->flags & CKF_OS_LOCKING_OK), CKR_CANT_LOCK);
130 g_return_val_if_fail ((args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) == 0, CKR_NEED_TO_CREATE_THREADS);
133 the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
134 the_certificates = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref);
135 the_assertions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_assertion);
137 initialized = TRUE;
138 return CKR_OK;
141 CK_RV
142 mock_C_Finalize (CK_VOID_PTR reserved)
144 g_return_val_if_fail (reserved == NULL, CKR_ARGUMENTS_BAD);
145 g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
147 initialized = FALSE;
149 g_hash_table_unref (the_certificates);
150 the_certificates = NULL;
152 g_hash_table_unref (the_assertions);
153 the_assertions = NULL;
155 g_hash_table_unref (the_sessions);
156 the_sessions = NULL;
158 return CKR_OK;
161 static const CK_INFO TEST_INFO = {
162 { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
163 "TEST MANUFACTURER ",
165 "TEST LIBRARY ",
166 { 45, 145 }
169 CK_RV
170 mock_C_GetInfo (CK_INFO_PTR info)
172 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
173 memcpy (info, &TEST_INFO, sizeof (*info));
174 return CKR_OK;
177 CK_RV
178 mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
180 g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
181 *list = &mock_default_functions;
182 return CKR_OK;
185 CK_RV
186 mock_C_GetSlotList (CK_BBOOL token_present,
187 CK_SLOT_ID_PTR slot_list,
188 CK_ULONG_PTR count)
190 CK_ULONG num = 1;
192 g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
194 /* Application only wants to know the number of slots. */
195 if (slot_list == NULL)
197 *count = num;
198 return CKR_OK;
201 if (*count < num)
202 g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
204 *count = num;
205 slot_list[0] = MOCK_SLOT_ONE_ID;
206 return CKR_OK;
209 /* Update mock-pkcs11.h URIs when updating this */
211 static const CK_SLOT_INFO MOCK_INFO_ONE = {
212 "MOCK SLOT ",
213 "MOCK MANUFACTURER ",
214 CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
215 { 55, 155 },
216 { 65, 165 },
219 CK_RV
220 mock_C_GetSlotInfo (CK_SLOT_ID slot_id,
221 CK_SLOT_INFO_PTR info)
223 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
225 if (slot_id == MOCK_SLOT_ONE_ID)
227 memcpy (info, &MOCK_INFO_ONE, sizeof (*info));
228 return CKR_OK;
230 else
232 g_return_val_if_reached (CKR_SLOT_ID_INVALID);
236 /* Update mock-pkcs11.h URIs when updating this */
238 static const CK_TOKEN_INFO MOCK_TOKEN_ONE = {
239 "MOCK LABEL ",
240 "MOCK MANUFACTURER ",
241 "MOCK MODEL ",
242 "MOCK SERIAL ",
243 CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED,
254 { 75, 175 },
255 { 85, 185 },
256 { '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
259 CK_RV
260 mock_C_GetTokenInfo (CK_SLOT_ID slot_id,
261 CK_TOKEN_INFO_PTR info)
263 g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
265 if (slot_id == MOCK_SLOT_ONE_ID)
267 memcpy (info, &MOCK_TOKEN_ONE, sizeof (*info));
268 return CKR_OK;
270 else
272 g_return_val_if_reached (CKR_SLOT_ID_INVALID);
276 CK_RV
277 mock_C_GetMechanismList (CK_SLOT_ID slot_id,
278 CK_MECHANISM_TYPE_PTR mechanism_list,
279 CK_ULONG_PTR count)
281 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
282 g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
284 /* Application only wants to know the number of slots. */
285 if (mechanism_list == NULL)
287 *count = 0;
288 return CKR_OK;
291 return CKR_OK;
294 CK_RV
295 mock_C_GetMechanismInfo (CK_SLOT_ID slot_id,
296 CK_MECHANISM_TYPE type,
297 CK_MECHANISM_INFO_PTR info)
299 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
300 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
302 g_return_val_if_reached (CKR_MECHANISM_INVALID);
305 CK_RV
306 mock_unsupported_C_InitToken (CK_SLOT_ID slot_id,
307 CK_UTF8CHAR_PTR pin,
308 CK_ULONG pin_len,
309 CK_UTF8CHAR_PTR label)
311 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
312 return CKR_FUNCTION_NOT_SUPPORTED;
315 CK_RV
316 mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags,
317 CK_SLOT_ID_PTR slot_id,
318 CK_VOID_PTR reserved)
320 return CKR_FUNCTION_NOT_SUPPORTED;
323 CK_RV
324 mock_C_OpenSession (CK_SLOT_ID slot_id,
325 CK_FLAGS flags,
326 CK_VOID_PTR application,
327 CK_NOTIFY notify,
328 CK_SESSION_HANDLE_PTR session)
330 Session *sess;
332 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
333 g_return_val_if_fail (session != NULL, CKR_ARGUMENTS_BAD);
334 g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
336 if (flags & CKF_RW_SESSION)
337 return CKR_TOKEN_WRITE_PROTECTED;
339 sess = g_new0 (Session, 1);
340 sess->handle = ++unique_identifier;
341 sess->info.flags = flags;
342 sess->info.slotID = slot_id;
343 sess->info.state = CKS_RO_PUBLIC_SESSION;
344 sess->info.ulDeviceError = 0;
345 *session = sess->handle;
347 g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
348 return CKR_OK;
351 CK_RV
352 mock_C_CloseSession (CK_SESSION_HANDLE session)
354 Session *sess;
356 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
357 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
359 g_hash_table_remove (the_sessions, GUINT_TO_POINTER (sess));
360 return CKR_OK;
363 CK_RV
364 mock_C_CloseAllSessions (CK_SLOT_ID slot_id)
366 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
368 g_hash_table_remove_all (the_sessions);
369 return CKR_OK;
372 CK_RV
373 mock_C_GetFunctionStatus (CK_SESSION_HANDLE session)
375 return CKR_FUNCTION_NOT_PARALLEL;
378 CK_RV
379 mock_C_CancelFunction (CK_SESSION_HANDLE session)
381 return CKR_FUNCTION_NOT_PARALLEL;
384 CK_RV
385 mock_C_GetSessionInfo (CK_SESSION_HANDLE session,
386 CK_SESSION_INFO_PTR info)
388 Session *sess;
390 g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
392 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
393 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
395 memcpy (info, &sess->info, sizeof (*info));
396 return CKR_OK;
399 CK_RV
400 mock_unsupported_C_InitPIN (CK_SESSION_HANDLE session,
401 CK_UTF8CHAR_PTR pin,
402 CK_ULONG pin_len)
404 return CKR_FUNCTION_NOT_SUPPORTED;
407 CK_RV
408 mock_unsupported_C_SetPIN (CK_SESSION_HANDLE session,
409 CK_UTF8CHAR_PTR old_pin,
410 CK_ULONG old_len,
411 CK_UTF8CHAR_PTR new_pin,
412 CK_ULONG new_len)
414 return CKR_FUNCTION_NOT_SUPPORTED;
417 CK_RV
418 mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE session,
419 CK_BYTE_PTR operation_state,
420 CK_ULONG_PTR operation_state_len)
422 return CKR_FUNCTION_NOT_SUPPORTED;
425 CK_RV
426 mock_unsupported_C_SetOperationState (CK_SESSION_HANDLE session,
427 CK_BYTE_PTR operation_state,
428 CK_ULONG operation_state_len,
429 CK_OBJECT_HANDLE encryption_key,
430 CK_OBJECT_HANDLE authentication_key)
432 return CKR_FUNCTION_NOT_SUPPORTED;
435 CK_RV
436 mock_unsupported_C_Login (CK_SESSION_HANDLE session,
437 CK_USER_TYPE user_type,
438 CK_UTF8CHAR_PTR pin,
439 CK_ULONG pin_len)
441 return CKR_FUNCTION_NOT_SUPPORTED;
444 CK_RV
445 mock_unsupported_C_Logout (CK_SESSION_HANDLE session)
447 return CKR_FUNCTION_NOT_SUPPORTED;
450 CK_RV
451 mock_readonly_C_CreateObject (CK_SESSION_HANDLE session,
452 CK_ATTRIBUTE_PTR template,
453 CK_ULONG count,
454 CK_OBJECT_HANDLE_PTR object)
456 Session *sess;
458 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
460 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
461 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
463 return CKR_TOKEN_WRITE_PROTECTED;
466 CK_RV
467 mock_unsupported_C_CopyObject (CK_SESSION_HANDLE session,
468 CK_OBJECT_HANDLE object,
469 CK_ATTRIBUTE_PTR template,
470 CK_ULONG count,
471 CK_OBJECT_HANDLE_PTR new_object)
473 return CKR_FUNCTION_NOT_SUPPORTED;
476 CK_RV
477 mock_readonly_C_DestroyObject (CK_SESSION_HANDLE session,
478 CK_OBJECT_HANDLE object)
480 Session *sess;
482 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
484 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
485 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
487 return CKR_TOKEN_WRITE_PROTECTED;
490 CK_RV
491 mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE session,
492 CK_OBJECT_HANDLE object,
493 CK_ULONG_PTR pulSize)
495 return CKR_FUNCTION_NOT_SUPPORTED;
498 static CK_RV
499 fill_data_attribute (CK_ATTRIBUTE *attr,
500 gconstpointer data,
501 gsize length)
503 if (!attr->pValue) {
504 attr->ulValueLen = length;
505 return CKR_OK;
506 } else if (attr->ulValueLen < length) {
507 attr->ulValueLen = length;
508 return CKR_BUFFER_TOO_SMALL;
509 } else {
510 memcpy (attr->pValue, data, length);
511 attr->ulValueLen = length;
512 return CKR_OK;
516 static CK_RV
517 fill_check_value_attribute (CK_ATTRIBUTE *attr,
518 GcrCertificate *cert)
520 guchar *data;
521 gsize length;
522 CK_RV rv;
524 data = gcr_certificate_get_fingerprint (cert, G_CHECKSUM_SHA1, &length);
525 rv = fill_data_attribute (attr, data, 3);
526 g_free (data);
528 return rv;
531 static CK_RV
532 fill_subject_attribute (CK_ATTRIBUTE *attr,
533 GcrCertificate *cert)
535 guchar *data;
536 gsize length;
537 CK_RV rv;
539 data = gcr_certificate_get_subject_raw (cert, &length);
540 rv = fill_data_attribute (attr, data, length);
541 g_free (data);
543 return rv;
546 static CK_RV
547 fill_issuer_attribute (CK_ATTRIBUTE *attr,
548 GcrCertificate *cert)
550 guchar *data;
551 gsize length;
552 CK_RV rv;
554 data = gcr_certificate_get_issuer_raw (cert, &length);
555 rv = fill_data_attribute (attr, data, length);
556 g_free (data);
558 return rv;
561 static CK_RV
562 fill_serial_attribute (CK_ATTRIBUTE *attr,
563 GcrCertificate *cert)
565 guchar *data;
566 gsize length;
567 CK_RV rv;
569 data = gcr_certificate_get_serial_number (cert, &length);
570 rv = fill_data_attribute (attr, data, length);
571 g_free (data);
573 return rv;
576 static CK_RV
577 fill_string_attribute (CK_ATTRIBUTE *attr,
578 const gchar *data)
580 return fill_data_attribute (attr, data, strlen (data));
583 static CK_RV
584 fill_id_attribute (CK_ATTRIBUTE *attr,
585 GcrCertificate *cert)
587 gchar *data;
588 CK_RV rv;
590 data = g_strdup_printf ("%p", cert);
591 rv = fill_string_attribute (attr, data);
592 g_free (data);
594 return rv;
597 static CK_RV
598 fill_value_attribute (CK_ATTRIBUTE *attr,
599 GcrCertificate *cert)
601 const guchar *data;
602 gsize length;
604 data = gcr_certificate_get_der_data (cert, &length);
605 return fill_data_attribute (attr, data, length);
608 static CK_RV
609 fill_ulong_attribute (CK_ATTRIBUTE *attr,
610 CK_ULONG value)
612 return fill_data_attribute (attr, &value, sizeof (value));
615 static CK_RV
616 fill_bool_attribute (CK_ATTRIBUTE *attr,
617 CK_BBOOL value)
619 return fill_data_attribute (attr, &value, sizeof (value));
622 static CK_RV
623 fill_certificate_attribute (CK_ATTRIBUTE *attr,
624 GcrCertificate *cert)
626 switch (attr->type)
628 case CKA_CLASS:
629 return fill_ulong_attribute (attr, CKO_CERTIFICATE);
630 case CKA_TOKEN:
631 return fill_bool_attribute (attr, CK_TRUE);
632 case CKA_PRIVATE:
633 case CKA_MODIFIABLE:
634 case CKA_TRUSTED:
635 return fill_bool_attribute (attr, CK_FALSE);
636 case CKA_LABEL:
637 return fill_string_attribute (attr, "Certificate");
638 case CKA_CERTIFICATE_TYPE:
639 return fill_ulong_attribute (attr, CKC_X_509);
640 case CKA_CERTIFICATE_CATEGORY:
641 return fill_ulong_attribute (attr, 2);
642 case CKA_CHECK_VALUE:
643 return fill_check_value_attribute (attr, cert);
644 case CKA_START_DATE:
645 case CKA_END_DATE:
646 return fill_data_attribute (attr, "", 0);
647 case CKA_SUBJECT:
648 return fill_subject_attribute (attr, cert);
649 case CKA_ID:
650 return fill_id_attribute (attr, cert);
651 case CKA_ISSUER:
652 return fill_issuer_attribute (attr, cert);
653 case CKA_SERIAL_NUMBER:
654 return fill_serial_attribute (attr, cert);
655 case CKA_VALUE:
656 return fill_value_attribute (attr, cert);
657 case CKA_URL:
658 case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
659 case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
660 case CKA_JAVA_MIDP_SECURITY_DOMAIN:
661 default:
662 return CKR_ATTRIBUTE_TYPE_INVALID;
666 static CK_RV
667 fill_assertion_attribute (CK_ATTRIBUTE *attr,
668 Assertion *assertion)
670 CK_RV rv;
672 switch (attr->type)
674 case CKA_CLASS:
675 return fill_ulong_attribute (attr, CKO_X_TRUST_ASSERTION);
676 case CKA_TOKEN:
677 return fill_bool_attribute (attr, CK_TRUE);
678 case CKA_PRIVATE:
679 case CKA_MODIFIABLE:
680 case CKA_TRUSTED:
681 return fill_bool_attribute (attr, CK_FALSE);
682 case CKA_LABEL:
683 return fill_string_attribute (attr, "Assertion");
684 case CKA_X_ASSERTION_TYPE:
685 return fill_ulong_attribute (attr, assertion->assertion_type);
686 case CKA_X_PURPOSE:
687 return fill_string_attribute (attr, assertion->purpose);
688 case CKA_X_PEER:
689 if (!assertion->peer)
690 return CKR_ATTRIBUTE_TYPE_INVALID;
691 return fill_string_attribute (attr, assertion->peer);
692 case CKA_SERIAL_NUMBER:
693 case CKA_ISSUER:
694 return fill_certificate_attribute (attr, assertion->cert);
695 case CKA_X_CERTIFICATE_VALUE:
696 attr->type = CKA_VALUE;
697 rv = fill_certificate_attribute (attr, assertion->cert);
698 attr->type = CKA_X_CERTIFICATE_VALUE;
699 return rv;
701 default:
702 return CKR_ATTRIBUTE_TYPE_INVALID;
706 CK_RV
707 mock_C_GetAttributeValue (CK_SESSION_HANDLE session,
708 CK_OBJECT_HANDLE object,
709 CK_ATTRIBUTE_PTR template,
710 CK_ULONG count)
712 CK_RV rv, ret = CKR_OK;
713 GcrCertificate *cert;
714 Assertion *assertion;
715 Session *sess;
716 CK_ULONG i;
718 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
719 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
721 cert = g_hash_table_lookup (the_certificates, GUINT_TO_POINTER (object));
722 assertion = g_hash_table_lookup (the_assertions, GUINT_TO_POINTER (object));
724 if (cert != NULL) {
725 for (i = 0; i < count; i++) {
726 rv = fill_certificate_attribute (template + i, cert);
727 if (rv != CKR_OK)
728 template[i].ulValueLen = (CK_ULONG)-1;
729 if (ret != CKR_OK)
730 ret = rv;
732 } else if (assertion != NULL) {
733 for (i = 0; i < count; i++) {
734 rv = fill_assertion_attribute (template + i, assertion);
735 if (rv != CKR_OK)
736 template[i].ulValueLen = (CK_ULONG)-1;
737 if (ret != CKR_OK)
738 ret = rv;
740 } else {
741 ret = CKR_OBJECT_HANDLE_INVALID;
744 return ret;
747 CK_RV
748 mock_readonly_C_SetAttributeValue (CK_SESSION_HANDLE session,
749 CK_OBJECT_HANDLE object,
750 CK_ATTRIBUTE_PTR template,
751 CK_ULONG count)
753 Session *sess;
755 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
756 g_return_val_if_fail (sess, CKR_SESSION_HANDLE_INVALID);
758 return CKR_TOKEN_WRITE_PROTECTED;
761 static gboolean
762 match_object_attributes (CK_SESSION_HANDLE session,
763 CK_ULONG object,
764 CK_ATTRIBUTE_PTR template,
765 CK_ULONG count)
767 CK_ATTRIBUTE_PTR values;
768 gboolean mismatch = FALSE;
769 CK_RV rv;
770 CK_ULONG i;
772 values = g_new0 (CK_ATTRIBUTE, count);
773 for (i = 0; i < count; i++) {
774 values[i].type = template[i].type;
775 if (template[i].ulValueLen != 0 &&
776 template[i].ulValueLen != (CK_ULONG)-1)
777 values[i].pValue = g_malloc (template[i].ulValueLen);
778 values[i].ulValueLen = template[i].ulValueLen;
781 rv = mock_C_GetAttributeValue (session, object, values, count);
783 if (rv == CKR_OK) {
784 for (i = 0; i < count; i++) {
785 if (gcr_comparable_memcmp (values[i].pValue, values[i].ulValueLen,
786 template[i].pValue, template[i].ulValueLen) != 0) {
787 mismatch = TRUE;
788 break;
793 for (i = 0; i < count; i++)
794 g_free (values[i].pValue);
795 g_free (values);
797 if (rv != CKR_OK)
798 return FALSE;
800 return !mismatch;
803 CK_RV
804 mock_C_FindObjectsInit (CK_SESSION_HANDLE session,
805 CK_ATTRIBUTE_PTR template,
806 CK_ULONG count)
808 GList *objects = NULL, *l;
809 Session *sess;
811 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
812 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
814 /* Starting an operation, cancels any previous one */
815 if (sess->operation != 0)
816 sess->operation = 0;
818 sess->operation = OP_FIND;
819 g_list_free (sess->matches);
820 sess->matches = NULL;
822 objects = g_list_concat (objects, g_hash_table_get_keys (the_certificates));
823 objects = g_list_concat (objects, g_hash_table_get_keys (the_assertions));
825 for (l = objects; l != NULL; l = g_list_next (l)) {
826 if (match_object_attributes (session, GPOINTER_TO_UINT (l->data), template, count))
827 sess->matches = g_list_prepend (sess->matches, l->data);
830 g_list_free (objects);
831 return CKR_OK;
834 CK_RV
835 mock_C_FindObjects (CK_SESSION_HANDLE session,
836 CK_OBJECT_HANDLE_PTR object,
837 CK_ULONG max_object_count,
838 CK_ULONG_PTR object_count)
840 Session *sess;
842 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
843 g_return_val_if_fail (object_count, CKR_ARGUMENTS_BAD);
844 g_return_val_if_fail (max_object_count != 0, CKR_ARGUMENTS_BAD);
846 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
847 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
848 g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
850 *object_count = 0;
851 while (max_object_count > 0 && sess->matches)
853 *object = GPOINTER_TO_UINT (sess->matches->data);
854 ++object;
855 --max_object_count;
856 ++(*object_count);
857 sess->matches = g_list_remove (sess->matches, sess->matches->data);
860 return CKR_OK;
863 CK_RV
864 mock_C_FindObjectsFinal (CK_SESSION_HANDLE session)
866 Session *sess;
868 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
869 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
870 g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
872 sess->operation = 0;
873 g_list_free (sess->matches);
874 sess->matches = NULL;
876 return CKR_OK;
879 CK_RV
880 mock_no_mechanisms_C_EncryptInit (CK_SESSION_HANDLE session,
881 CK_MECHANISM_PTR mechanism,
882 CK_OBJECT_HANDLE key)
884 Session *sess;
886 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
887 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
889 return CKR_MECHANISM_INVALID;
892 CK_RV
893 mock_not_initialized_C_Encrypt (CK_SESSION_HANDLE session,
894 CK_BYTE_PTR data,
895 CK_ULONG data_len,
896 CK_BYTE_PTR encrypted_data,
897 CK_ULONG_PTR encrypted_data_len)
899 return CKR_OPERATION_NOT_INITIALIZED;
902 CK_RV
903 mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE session,
904 CK_BYTE_PTR part,
905 CK_ULONG part_len,
906 CK_BYTE_PTR encrypted_part,
907 CK_ULONG_PTR encrypted_part_len)
909 return CKR_FUNCTION_NOT_SUPPORTED;
912 CK_RV
913 mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE session,
914 CK_BYTE_PTR last_encrypted_part,
915 CK_ULONG_PTR last_encrypted_part_len)
917 return CKR_FUNCTION_NOT_SUPPORTED;
920 CK_RV
921 mock_no_mechanisms_C_DecryptInit (CK_SESSION_HANDLE session,
922 CK_MECHANISM_PTR mechanism,
923 CK_OBJECT_HANDLE key)
925 Session *sess;
927 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
928 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
930 return CKR_MECHANISM_INVALID;
933 CK_RV
934 mock_not_initialized_C_Decrypt (CK_SESSION_HANDLE session,
935 CK_BYTE_PTR encrypted_data,
936 CK_ULONG encrypted_data_len,
937 CK_BYTE_PTR data,
938 CK_ULONG_PTR data_len)
940 return CKR_OPERATION_NOT_INITIALIZED;
943 CK_RV
944 mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE session,
945 CK_BYTE_PTR encrypted_part,
946 CK_ULONG encrypted_key_len,
947 CK_BYTE_PTR part,
948 CK_ULONG_PTR part_len)
950 return CKR_FUNCTION_NOT_SUPPORTED;
953 CK_RV
954 mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE session,
955 CK_BYTE_PTR last_part,
956 CK_ULONG_PTR last_part_len)
958 return CKR_FUNCTION_NOT_SUPPORTED;
961 CK_RV
962 mock_unsupported_C_DigestInit (CK_SESSION_HANDLE session,
963 CK_MECHANISM_PTR mechanism)
965 return CKR_FUNCTION_NOT_SUPPORTED;
968 CK_RV
969 mock_unsupported_C_Digest (CK_SESSION_HANDLE session,
970 CK_BYTE_PTR data,
971 CK_ULONG data_len,
972 CK_BYTE_PTR digest,
973 CK_ULONG_PTR digest_len)
975 return CKR_FUNCTION_NOT_SUPPORTED;
978 CK_RV
979 mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE session,
980 CK_BYTE_PTR part,
981 CK_ULONG part_len)
983 return CKR_FUNCTION_NOT_SUPPORTED;
986 CK_RV
987 mock_unsupported_C_DigestKey (CK_SESSION_HANDLE session,
988 CK_OBJECT_HANDLE key)
990 return CKR_FUNCTION_NOT_SUPPORTED;
993 CK_RV
994 mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE session,
995 CK_BYTE_PTR digest,
996 CK_ULONG_PTR digest_len)
998 return CKR_FUNCTION_NOT_SUPPORTED;
1001 CK_RV
1002 mock_no_mechanisms_C_SignInit (CK_SESSION_HANDLE session,
1003 CK_MECHANISM_PTR mechanism,
1004 CK_OBJECT_HANDLE key)
1006 Session *sess;
1008 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1009 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1011 return CKR_MECHANISM_INVALID;
1014 CK_RV
1015 mock_not_initialized_C_Sign (CK_SESSION_HANDLE session,
1016 CK_BYTE_PTR data,
1017 CK_ULONG data_len,
1018 CK_BYTE_PTR signature,
1019 CK_ULONG_PTR signature_len)
1021 return CKR_OPERATION_NOT_INITIALIZED;
1024 CK_RV
1025 mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE session,
1026 CK_BYTE_PTR part,
1027 CK_ULONG part_len)
1029 return CKR_FUNCTION_NOT_SUPPORTED;
1032 CK_RV
1033 mock_unsupported_C_SignFinal (CK_SESSION_HANDLE session,
1034 CK_BYTE_PTR signature,
1035 CK_ULONG_PTR signature_len)
1037 return CKR_FUNCTION_NOT_SUPPORTED;
1040 CK_RV
1041 mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE session,
1042 CK_MECHANISM_PTR mechanism,
1043 CK_OBJECT_HANDLE key)
1045 return CKR_FUNCTION_NOT_SUPPORTED;
1048 CK_RV
1049 mock_unsupported_C_SignRecover (CK_SESSION_HANDLE session,
1050 CK_BYTE_PTR data,
1051 CK_ULONG data_len,
1052 CK_BYTE_PTR signature,
1053 CK_ULONG_PTR signature_len)
1055 return CKR_FUNCTION_NOT_SUPPORTED;
1058 CK_RV
1059 mock_no_mechanisms_C_VerifyInit (CK_SESSION_HANDLE session,
1060 CK_MECHANISM_PTR mechanism,
1061 CK_OBJECT_HANDLE key)
1063 Session *sess;
1065 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1066 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1068 return CKR_MECHANISM_INVALID;
1071 CK_RV
1072 mock_not_initialized_C_Verify (CK_SESSION_HANDLE session,
1073 CK_BYTE_PTR data,
1074 CK_ULONG data_len,
1075 CK_BYTE_PTR signature,
1076 CK_ULONG signature_len)
1078 return CKR_OPERATION_NOT_INITIALIZED;
1081 CK_RV
1082 mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE session,
1083 CK_BYTE_PTR part,
1084 CK_ULONG part_len)
1086 return CKR_FUNCTION_NOT_SUPPORTED;
1089 CK_RV
1090 mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE session,
1091 CK_BYTE_PTR signature,
1092 CK_ULONG signature_len)
1094 return CKR_FUNCTION_NOT_SUPPORTED;
1097 CK_RV
1098 mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE session,
1099 CK_MECHANISM_PTR mechanism,
1100 CK_OBJECT_HANDLE key)
1102 return CKR_FUNCTION_NOT_SUPPORTED;
1105 CK_RV
1106 mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE session,
1107 CK_BYTE_PTR signature,
1108 CK_ULONG signature_len,
1109 CK_BYTE_PTR data,
1110 CK_ULONG_PTR data_len)
1112 return CKR_FUNCTION_NOT_SUPPORTED;
1115 CK_RV
1116 mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE session,
1117 CK_BYTE_PTR part,
1118 CK_ULONG part_len,
1119 CK_BYTE_PTR encrypted_part,
1120 CK_ULONG_PTR encrypted_key_len)
1122 return CKR_FUNCTION_NOT_SUPPORTED;
1125 CK_RV
1126 mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE session,
1127 CK_BYTE_PTR encrypted_part,
1128 CK_ULONG encrypted_key_len,
1129 CK_BYTE_PTR part,
1130 CK_ULONG_PTR part_len)
1132 return CKR_FUNCTION_NOT_SUPPORTED;
1135 CK_RV
1136 mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE session,
1137 CK_BYTE_PTR part,
1138 CK_ULONG part_len,
1139 CK_BYTE_PTR encrypted_part,
1140 CK_ULONG_PTR encrypted_key_len)
1142 return CKR_FUNCTION_NOT_SUPPORTED;
1145 CK_RV
1146 mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE session,
1147 CK_BYTE_PTR encrypted_part,
1148 CK_ULONG encrypted_key_len,
1149 CK_BYTE_PTR part,
1150 CK_ULONG_PTR part_len)
1152 return CKR_FUNCTION_NOT_SUPPORTED;
1155 CK_RV
1156 mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE session,
1157 CK_MECHANISM_PTR mechanism,
1158 CK_ATTRIBUTE_PTR template,
1159 CK_ULONG count,
1160 CK_OBJECT_HANDLE_PTR key)
1162 return CKR_FUNCTION_NOT_SUPPORTED;
1165 CK_RV
1166 mock_no_mechanisms_C_GenerateKeyPair (CK_SESSION_HANDLE session,
1167 CK_MECHANISM_PTR mechanism,
1168 CK_ATTRIBUTE_PTR public_key_template,
1169 CK_ULONG public_key_attribute_count,
1170 CK_ATTRIBUTE_PTR private_key_template,
1171 CK_ULONG private_key_attribute_count,
1172 CK_OBJECT_HANDLE_PTR public_key,
1173 CK_OBJECT_HANDLE_PTR private_key)
1175 Session *sess;
1177 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1178 g_return_val_if_fail (public_key_template, CKR_TEMPLATE_INCOMPLETE);
1179 g_return_val_if_fail (public_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1180 g_return_val_if_fail (private_key_template, CKR_TEMPLATE_INCOMPLETE);
1181 g_return_val_if_fail (private_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1182 g_return_val_if_fail (public_key, CKR_ARGUMENTS_BAD);
1183 g_return_val_if_fail (private_key, CKR_ARGUMENTS_BAD);
1185 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1186 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1188 return CKR_MECHANISM_INVALID;
1191 CK_RV
1192 mock_no_mechanisms_C_WrapKey (CK_SESSION_HANDLE session,
1193 CK_MECHANISM_PTR mechanism,
1194 CK_OBJECT_HANDLE wrapping_key,
1195 CK_OBJECT_HANDLE key,
1196 CK_BYTE_PTR wrapped_key,
1197 CK_ULONG_PTR wrapped_key_len)
1199 Session *sess;
1201 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1202 g_return_val_if_fail (wrapping_key, CKR_OBJECT_HANDLE_INVALID);
1203 g_return_val_if_fail (key, CKR_OBJECT_HANDLE_INVALID);
1204 g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1206 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1207 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1209 return CKR_MECHANISM_INVALID;
1212 CK_RV
1213 mock_no_mechanisms_C_UnwrapKey (CK_SESSION_HANDLE session,
1214 CK_MECHANISM_PTR mechanism,
1215 CK_OBJECT_HANDLE unwrapping_key,
1216 CK_BYTE_PTR wrapped_key,
1217 CK_ULONG wrapped_key_len,
1218 CK_ATTRIBUTE_PTR template,
1219 CK_ULONG count,
1220 CK_OBJECT_HANDLE_PTR key)
1222 Session *sess;
1224 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1225 g_return_val_if_fail (unwrapping_key, CKR_WRAPPING_KEY_HANDLE_INVALID);
1226 g_return_val_if_fail (wrapped_key, CKR_WRAPPED_KEY_INVALID);
1227 g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1228 g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1229 g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1230 g_return_val_if_fail (count, CKR_TEMPLATE_INCONSISTENT);
1232 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1233 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1235 return CKR_MECHANISM_INVALID;
1238 CK_RV
1239 mock_no_mechanisms_C_DeriveKey (CK_SESSION_HANDLE session,
1240 CK_MECHANISM_PTR mechanism,
1241 CK_OBJECT_HANDLE base_key,
1242 CK_ATTRIBUTE_PTR template,
1243 CK_ULONG count,
1244 CK_OBJECT_HANDLE_PTR key)
1246 Session *sess;
1248 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1249 g_return_val_if_fail (count, CKR_TEMPLATE_INCOMPLETE);
1250 g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1251 g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1253 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1254 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1256 return CKR_MECHANISM_INVALID;
1259 CK_RV
1260 mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE session,
1261 CK_BYTE_PTR pSeed,
1262 CK_ULONG seed_len)
1264 return CKR_FUNCTION_NOT_SUPPORTED;
1267 CK_RV
1268 mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE session,
1269 CK_BYTE_PTR random_data,
1270 CK_ULONG random_len)
1272 return CKR_FUNCTION_NOT_SUPPORTED;
1275 CK_FUNCTION_LIST mock_default_functions = {
1276 { 2, 11 }, /* version */
1277 mock_C_Initialize,
1278 mock_C_Finalize,
1279 mock_C_GetInfo,
1280 mock_C_GetFunctionList,
1281 mock_C_GetSlotList,
1282 mock_C_GetSlotInfo,
1283 mock_C_GetTokenInfo,
1284 mock_C_GetMechanismList,
1285 mock_C_GetMechanismInfo,
1286 mock_unsupported_C_InitToken,
1287 mock_unsupported_C_InitPIN,
1288 mock_unsupported_C_SetPIN,
1289 mock_C_OpenSession,
1290 mock_C_CloseSession,
1291 mock_C_CloseAllSessions,
1292 mock_C_GetSessionInfo,
1293 mock_unsupported_C_GetOperationState,
1294 mock_unsupported_C_SetOperationState,
1295 mock_unsupported_C_Login,
1296 mock_unsupported_C_Logout,
1297 mock_readonly_C_CreateObject,
1298 mock_unsupported_C_CopyObject,
1299 mock_readonly_C_DestroyObject,
1300 mock_unsupported_C_GetObjectSize,
1301 mock_C_GetAttributeValue,
1302 mock_readonly_C_SetAttributeValue,
1303 mock_C_FindObjectsInit,
1304 mock_C_FindObjects,
1305 mock_C_FindObjectsFinal,
1306 mock_no_mechanisms_C_EncryptInit,
1307 mock_not_initialized_C_Encrypt,
1308 mock_unsupported_C_EncryptUpdate,
1309 mock_unsupported_C_EncryptFinal,
1310 mock_no_mechanisms_C_DecryptInit,
1311 mock_not_initialized_C_Decrypt,
1312 mock_unsupported_C_DecryptUpdate,
1313 mock_unsupported_C_DecryptFinal,
1314 mock_unsupported_C_DigestInit,
1315 mock_unsupported_C_Digest,
1316 mock_unsupported_C_DigestUpdate,
1317 mock_unsupported_C_DigestKey,
1318 mock_unsupported_C_DigestFinal,
1319 mock_no_mechanisms_C_SignInit,
1320 mock_not_initialized_C_Sign,
1321 mock_unsupported_C_SignUpdate,
1322 mock_unsupported_C_SignFinal,
1323 mock_unsupported_C_SignRecoverInit,
1324 mock_unsupported_C_SignRecover,
1325 mock_no_mechanisms_C_VerifyInit,
1326 mock_not_initialized_C_Verify,
1327 mock_unsupported_C_VerifyUpdate,
1328 mock_unsupported_C_VerifyFinal,
1329 mock_unsupported_C_VerifyRecoverInit,
1330 mock_unsupported_C_VerifyRecover,
1331 mock_unsupported_C_DigestEncryptUpdate,
1332 mock_unsupported_C_DecryptDigestUpdate,
1333 mock_unsupported_C_SignEncryptUpdate,
1334 mock_unsupported_C_DecryptVerifyUpdate,
1335 mock_unsupported_C_GenerateKey,
1336 mock_no_mechanisms_C_GenerateKeyPair,
1337 mock_no_mechanisms_C_WrapKey,
1338 mock_no_mechanisms_C_UnwrapKey,
1339 mock_no_mechanisms_C_DeriveKey,
1340 mock_unsupported_C_SeedRandom,
1341 mock_unsupported_C_GenerateRandom,
1342 mock_C_GetFunctionStatus,
1343 mock_C_CancelFunction,
1344 mock_unsupported_C_WaitForSlotEvent