Revert "log-window: escape the body of the message"
[empathy-mirror.git] / tests / mock-pkcs11.c
blob4b1219f2c35a99eb54fa924d980990b534ae40cd
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., 59 Temple Place - Suite 330, Boston, MA
18 * 02111-1307, USA.
21 #include "config.h"
23 #include "mock-pkcs11.h"
25 #include <gcr/gcr.h>
27 #include <glib.h>
29 #include <string.h>
32 * This is *NOT* how you'd want to implement a PKCS#11 module. This
33 * fake module simply provides enough for gnutls-pkcs11 backend to test against.
34 * It doesn't pass any tests, or behave as expected from a PKCS#11 module.
37 static gboolean initialized = FALSE;
39 typedef enum {
40 OP_FIND = 1,
41 } Operation;
43 static CK_OBJECT_HANDLE unique_identifier = 100;
44 static GHashTable *the_sessions = NULL;
45 static GHashTable *the_certificates = NULL;
46 static GHashTable *the_assertions = NULL;
48 typedef struct {
49 GcrCertificate *cert;
50 CK_ULONG assertion_type;
51 gchar *purpose;
52 gchar *peer;
53 } Assertion;
55 static void
56 free_assertion (gpointer data)
58 Assertion *assertion = data;
59 g_clear_object (&assertion->cert);
60 g_free (assertion->purpose);
61 g_free (assertion->peer);
62 g_free (assertion);
65 typedef struct {
66 CK_SESSION_HANDLE handle;
67 CK_SESSION_INFO info;
69 Operation operation;
71 /* For find operations */
72 GList *matches;
73 } Session;
75 static void
76 free_session (gpointer data)
78 Session *sess = (Session*)data;
79 g_list_free (sess->matches);
80 g_free (sess);
83 CK_OBJECT_HANDLE
84 mock_module_add_certificate (GcrCertificate *cert)
86 CK_OBJECT_HANDLE handle;
88 g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
90 handle = unique_identifier++;
91 g_hash_table_insert (the_certificates, GUINT_TO_POINTER (handle), g_object_ref (cert));
92 return handle;
95 CK_OBJECT_HANDLE
96 mock_module_add_assertion (GcrCertificate *cert,
97 CK_X_ASSERTION_TYPE assertion_type,
98 const gchar *purpose,
99 const gchar *peer)
101 Assertion *assertion;
102 CK_OBJECT_HANDLE handle;
104 g_return_val_if_fail (GCR_IS_CERTIFICATE (cert), 0);
106 assertion = g_new0 (Assertion, 1);
107 assertion->cert = g_object_ref (cert);
108 assertion->assertion_type = assertion_type;
109 assertion->purpose = g_strdup (purpose);
110 assertion->peer = g_strdup (peer);
112 handle = unique_identifier++;
113 g_hash_table_insert (the_assertions, GUINT_TO_POINTER (handle), assertion);
114 return handle;
117 CK_RV
118 mock_C_Initialize (CK_VOID_PTR init_args)
120 CK_C_INITIALIZE_ARGS_PTR args;
122 g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
124 args = (CK_C_INITIALIZE_ARGS_PTR)init_args;
125 if (args)
127 g_return_val_if_fail(
128 (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
129 args->LockMutex == NULL && args->UnlockMutex == NULL) ||
130 (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
131 args->LockMutex != NULL && args->UnlockMutex != NULL),
132 CKR_ARGUMENTS_BAD);
134 /* Flags should allow OS locking and os threads */
135 g_return_val_if_fail ((args->flags & CKF_OS_LOCKING_OK), CKR_CANT_LOCK);
136 g_return_val_if_fail ((args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) == 0, CKR_NEED_TO_CREATE_THREADS);
139 the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
140 the_certificates = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref);
141 the_assertions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_assertion);
143 initialized = TRUE;
144 return CKR_OK;
147 CK_RV
148 mock_C_Finalize (CK_VOID_PTR reserved)
150 g_return_val_if_fail (reserved == NULL, CKR_ARGUMENTS_BAD);
151 g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
153 initialized = FALSE;
155 g_hash_table_destroy (the_certificates);
156 the_certificates = NULL;
158 g_hash_table_destroy (the_assertions);
159 the_assertions = NULL;
161 g_hash_table_destroy (the_sessions);
162 the_sessions = NULL;
164 return CKR_OK;
167 static const CK_INFO TEST_INFO = {
168 { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
169 "TEST MANUFACTURER ",
171 "TEST LIBRARY ",
172 { 45, 145 }
175 CK_RV
176 mock_C_GetInfo (CK_INFO_PTR info)
178 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
179 memcpy (info, &TEST_INFO, sizeof (*info));
180 return CKR_OK;
183 CK_RV
184 mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
186 g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
187 *list = &mock_default_functions;
188 return CKR_OK;
191 CK_RV
192 mock_C_GetSlotList (CK_BBOOL token_present,
193 CK_SLOT_ID_PTR slot_list,
194 CK_ULONG_PTR count)
196 CK_ULONG num = 1;
198 g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
200 /* Application only wants to know the number of slots. */
201 if (slot_list == NULL)
203 *count = num;
204 return CKR_OK;
207 if (*count < num)
208 g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
210 *count = num;
211 slot_list[0] = MOCK_SLOT_ONE_ID;
212 return CKR_OK;
215 /* Update mock-pkcs11.h URIs when updating this */
217 static const CK_SLOT_INFO MOCK_INFO_ONE = {
218 "MOCK SLOT ",
219 "MOCK MANUFACTURER ",
220 CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
221 { 55, 155 },
222 { 65, 165 },
225 CK_RV
226 mock_C_GetSlotInfo (CK_SLOT_ID slot_id,
227 CK_SLOT_INFO_PTR info)
229 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
231 if (slot_id == MOCK_SLOT_ONE_ID)
233 memcpy (info, &MOCK_INFO_ONE, sizeof (*info));
234 return CKR_OK;
236 else
238 g_return_val_if_reached (CKR_SLOT_ID_INVALID);
242 /* Update mock-pkcs11.h URIs when updating this */
244 static const CK_TOKEN_INFO MOCK_TOKEN_ONE = {
245 "MOCK LABEL ",
246 "MOCK MANUFACTURER ",
247 "MOCK MODEL ",
248 "MOCK SERIAL ",
249 CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED,
260 { 75, 175 },
261 { 85, 185 },
262 { '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
265 CK_RV
266 mock_C_GetTokenInfo (CK_SLOT_ID slot_id,
267 CK_TOKEN_INFO_PTR info)
269 g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
271 if (slot_id == MOCK_SLOT_ONE_ID)
273 memcpy (info, &MOCK_TOKEN_ONE, sizeof (*info));
274 return CKR_OK;
276 else
278 g_return_val_if_reached (CKR_SLOT_ID_INVALID);
282 CK_RV
283 mock_C_GetMechanismList (CK_SLOT_ID slot_id,
284 CK_MECHANISM_TYPE_PTR mechanism_list,
285 CK_ULONG_PTR count)
287 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
288 g_return_val_if_fail (count, CKR_ARGUMENTS_BAD);
290 /* Application only wants to know the number of slots. */
291 if (mechanism_list == NULL)
293 *count = 0;
294 return CKR_OK;
297 return CKR_OK;
300 CK_RV
301 mock_C_GetMechanismInfo (CK_SLOT_ID slot_id,
302 CK_MECHANISM_TYPE type,
303 CK_MECHANISM_INFO_PTR info)
305 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
306 g_return_val_if_fail (info, CKR_ARGUMENTS_BAD);
308 g_return_val_if_reached (CKR_MECHANISM_INVALID);
311 CK_RV
312 mock_unsupported_C_InitToken (CK_SLOT_ID slot_id,
313 CK_UTF8CHAR_PTR pin,
314 CK_ULONG pin_len,
315 CK_UTF8CHAR_PTR label)
317 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
318 return CKR_FUNCTION_NOT_SUPPORTED;
321 CK_RV
322 mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags,
323 CK_SLOT_ID_PTR slot_id,
324 CK_VOID_PTR reserved)
326 return CKR_FUNCTION_NOT_SUPPORTED;
329 CK_RV
330 mock_C_OpenSession (CK_SLOT_ID slot_id,
331 CK_FLAGS flags,
332 CK_VOID_PTR application,
333 CK_NOTIFY notify,
334 CK_SESSION_HANDLE_PTR session)
336 Session *sess;
338 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
339 g_return_val_if_fail (session != NULL, CKR_ARGUMENTS_BAD);
340 g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
342 if (flags & CKF_RW_SESSION)
343 return CKR_TOKEN_WRITE_PROTECTED;
345 sess = g_new0 (Session, 1);
346 sess->handle = ++unique_identifier;
347 sess->info.flags = flags;
348 sess->info.slotID = slot_id;
349 sess->info.state = CKS_RO_PUBLIC_SESSION;
350 sess->info.ulDeviceError = 0;
351 *session = sess->handle;
353 g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
354 return CKR_OK;
357 CK_RV
358 mock_C_CloseSession (CK_SESSION_HANDLE session)
360 Session *sess;
362 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
363 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
365 g_hash_table_remove (the_sessions, GUINT_TO_POINTER (sess));
366 return CKR_OK;
369 CK_RV
370 mock_C_CloseAllSessions (CK_SLOT_ID slot_id)
372 g_return_val_if_fail (slot_id == MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
374 g_hash_table_remove_all (the_sessions);
375 return CKR_OK;
378 CK_RV
379 mock_C_GetFunctionStatus (CK_SESSION_HANDLE session)
381 return CKR_FUNCTION_NOT_PARALLEL;
384 CK_RV
385 mock_C_CancelFunction (CK_SESSION_HANDLE session)
387 return CKR_FUNCTION_NOT_PARALLEL;
390 CK_RV
391 mock_C_GetSessionInfo (CK_SESSION_HANDLE session,
392 CK_SESSION_INFO_PTR info)
394 Session *sess;
396 g_return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
398 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
399 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
401 memcpy (info, &sess->info, sizeof (*info));
402 return CKR_OK;
405 CK_RV
406 mock_unsupported_C_InitPIN (CK_SESSION_HANDLE session,
407 CK_UTF8CHAR_PTR pin,
408 CK_ULONG pin_len)
410 return CKR_FUNCTION_NOT_SUPPORTED;
413 CK_RV
414 mock_unsupported_C_SetPIN (CK_SESSION_HANDLE session,
415 CK_UTF8CHAR_PTR old_pin,
416 CK_ULONG old_len,
417 CK_UTF8CHAR_PTR new_pin,
418 CK_ULONG new_len)
420 return CKR_FUNCTION_NOT_SUPPORTED;
423 CK_RV
424 mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE session,
425 CK_BYTE_PTR operation_state,
426 CK_ULONG_PTR operation_state_len)
428 return CKR_FUNCTION_NOT_SUPPORTED;
431 CK_RV
432 mock_unsupported_C_SetOperationState (CK_SESSION_HANDLE session,
433 CK_BYTE_PTR operation_state,
434 CK_ULONG operation_state_len,
435 CK_OBJECT_HANDLE encryption_key,
436 CK_OBJECT_HANDLE authentication_key)
438 return CKR_FUNCTION_NOT_SUPPORTED;
441 CK_RV
442 mock_unsupported_C_Login (CK_SESSION_HANDLE session,
443 CK_USER_TYPE user_type,
444 CK_UTF8CHAR_PTR pin,
445 CK_ULONG pin_len)
447 return CKR_FUNCTION_NOT_SUPPORTED;
450 CK_RV
451 mock_unsupported_C_Logout (CK_SESSION_HANDLE session)
453 return CKR_FUNCTION_NOT_SUPPORTED;
456 CK_RV
457 mock_readonly_C_CreateObject (CK_SESSION_HANDLE session,
458 CK_ATTRIBUTE_PTR template,
459 CK_ULONG count,
460 CK_OBJECT_HANDLE_PTR object)
462 Session *sess;
464 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
466 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
467 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
469 return CKR_TOKEN_WRITE_PROTECTED;
472 CK_RV
473 mock_unsupported_C_CopyObject (CK_SESSION_HANDLE session,
474 CK_OBJECT_HANDLE object,
475 CK_ATTRIBUTE_PTR template,
476 CK_ULONG count,
477 CK_OBJECT_HANDLE_PTR new_object)
479 return CKR_FUNCTION_NOT_SUPPORTED;
482 CK_RV
483 mock_readonly_C_DestroyObject (CK_SESSION_HANDLE session,
484 CK_OBJECT_HANDLE object)
486 Session *sess;
488 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
490 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
491 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
493 return CKR_TOKEN_WRITE_PROTECTED;
496 CK_RV
497 mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE session,
498 CK_OBJECT_HANDLE object,
499 CK_ULONG_PTR pulSize)
501 return CKR_FUNCTION_NOT_SUPPORTED;
504 static CK_RV
505 fill_data_attribute (CK_ATTRIBUTE *attr,
506 gconstpointer data,
507 gsize length)
509 if (!attr->pValue) {
510 attr->ulValueLen = length;
511 return CKR_OK;
512 } else if (attr->ulValueLen < length) {
513 attr->ulValueLen = length;
514 return CKR_BUFFER_TOO_SMALL;
515 } else {
516 memcpy (attr->pValue, data, length);
517 attr->ulValueLen = length;
518 return CKR_OK;
522 static CK_RV
523 fill_check_value_attribute (CK_ATTRIBUTE *attr,
524 GcrCertificate *cert)
526 guchar *data;
527 gsize length;
528 CK_RV rv;
530 data = gcr_certificate_get_fingerprint (cert, G_CHECKSUM_SHA1, &length);
531 rv = fill_data_attribute (attr, data, 3);
532 g_free (data);
534 return rv;
537 static CK_RV
538 fill_subject_attribute (CK_ATTRIBUTE *attr,
539 GcrCertificate *cert)
541 guchar *data;
542 gsize length;
543 CK_RV rv;
545 data = gcr_certificate_get_subject_raw (cert, &length);
546 rv = fill_data_attribute (attr, data, length);
547 g_free (data);
549 return rv;
552 static CK_RV
553 fill_issuer_attribute (CK_ATTRIBUTE *attr,
554 GcrCertificate *cert)
556 guchar *data;
557 gsize length;
558 CK_RV rv;
560 data = gcr_certificate_get_issuer_raw (cert, &length);
561 rv = fill_data_attribute (attr, data, length);
562 g_free (data);
564 return rv;
567 static CK_RV
568 fill_serial_attribute (CK_ATTRIBUTE *attr,
569 GcrCertificate *cert)
571 guchar *data;
572 gsize length;
573 CK_RV rv;
575 data = gcr_certificate_get_serial_number (cert, &length);
576 rv = fill_data_attribute (attr, data, length);
577 g_free (data);
579 return rv;
582 static CK_RV
583 fill_string_attribute (CK_ATTRIBUTE *attr,
584 const gchar *data)
586 return fill_data_attribute (attr, data, strlen (data));
589 static CK_RV
590 fill_id_attribute (CK_ATTRIBUTE *attr,
591 GcrCertificate *cert)
593 gchar *data;
594 CK_RV rv;
596 data = g_strdup_printf ("%p", cert);
597 rv = fill_string_attribute (attr, data);
598 g_free (data);
600 return rv;
603 static CK_RV
604 fill_value_attribute (CK_ATTRIBUTE *attr,
605 GcrCertificate *cert)
607 const guchar *data;
608 gsize length;
610 data = gcr_certificate_get_der_data (cert, &length);
611 return fill_data_attribute (attr, data, length);
614 static CK_RV
615 fill_ulong_attribute (CK_ATTRIBUTE *attr,
616 CK_ULONG value)
618 return fill_data_attribute (attr, &value, sizeof (value));
621 static CK_RV
622 fill_bool_attribute (CK_ATTRIBUTE *attr,
623 CK_BBOOL value)
625 return fill_data_attribute (attr, &value, sizeof (value));
628 static CK_RV
629 fill_certificate_attribute (CK_ATTRIBUTE *attr,
630 GcrCertificate *cert)
632 switch (attr->type)
634 case CKA_CLASS:
635 return fill_ulong_attribute (attr, CKO_CERTIFICATE);
636 case CKA_TOKEN:
637 return fill_bool_attribute (attr, CK_TRUE);
638 case CKA_PRIVATE:
639 case CKA_MODIFIABLE:
640 case CKA_TRUSTED:
641 return fill_bool_attribute (attr, CK_FALSE);
642 case CKA_LABEL:
643 return fill_string_attribute (attr, "Certificate");
644 case CKA_CERTIFICATE_TYPE:
645 return fill_ulong_attribute (attr, CKC_X_509);
646 case CKA_CERTIFICATE_CATEGORY:
647 return fill_ulong_attribute (attr, 2);
648 case CKA_CHECK_VALUE:
649 return fill_check_value_attribute (attr, cert);
650 case CKA_START_DATE:
651 case CKA_END_DATE:
652 return fill_data_attribute (attr, "", 0);
653 case CKA_SUBJECT:
654 return fill_subject_attribute (attr, cert);
655 case CKA_ID:
656 return fill_id_attribute (attr, cert);
657 case CKA_ISSUER:
658 return fill_issuer_attribute (attr, cert);
659 case CKA_SERIAL_NUMBER:
660 return fill_serial_attribute (attr, cert);
661 case CKA_VALUE:
662 return fill_value_attribute (attr, cert);
663 case CKA_URL:
664 case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
665 case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
666 case CKA_JAVA_MIDP_SECURITY_DOMAIN:
667 default:
668 return CKR_ATTRIBUTE_TYPE_INVALID;
672 static CK_RV
673 fill_assertion_attribute (CK_ATTRIBUTE *attr,
674 Assertion *assertion)
676 CK_RV rv;
678 switch (attr->type)
680 case CKA_CLASS:
681 return fill_ulong_attribute (attr, CKO_X_TRUST_ASSERTION);
682 case CKA_TOKEN:
683 return fill_bool_attribute (attr, CK_TRUE);
684 case CKA_PRIVATE:
685 case CKA_MODIFIABLE:
686 case CKA_TRUSTED:
687 return fill_bool_attribute (attr, CK_FALSE);
688 case CKA_LABEL:
689 return fill_string_attribute (attr, "Assertion");
690 case CKA_X_ASSERTION_TYPE:
691 return fill_ulong_attribute (attr, assertion->assertion_type);
692 case CKA_X_PURPOSE:
693 return fill_string_attribute (attr, assertion->purpose);
694 case CKA_X_PEER:
695 if (!assertion->peer)
696 return CKR_ATTRIBUTE_TYPE_INVALID;
697 return fill_string_attribute (attr, assertion->peer);
698 case CKA_SERIAL_NUMBER:
699 case CKA_ISSUER:
700 return fill_certificate_attribute (attr, assertion->cert);
701 case CKA_X_CERTIFICATE_VALUE:
702 attr->type = CKA_VALUE;
703 rv = fill_certificate_attribute (attr, assertion->cert);
704 attr->type = CKA_X_CERTIFICATE_VALUE;
705 return rv;
707 default:
708 return CKR_ATTRIBUTE_TYPE_INVALID;
712 CK_RV
713 mock_C_GetAttributeValue (CK_SESSION_HANDLE session,
714 CK_OBJECT_HANDLE object,
715 CK_ATTRIBUTE_PTR template,
716 CK_ULONG count)
718 CK_RV rv, ret = CKR_OK;
719 GcrCertificate *cert;
720 Assertion *assertion;
721 Session *sess;
722 CK_ULONG i;
724 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
725 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
727 cert = g_hash_table_lookup (the_certificates, GUINT_TO_POINTER (object));
728 assertion = g_hash_table_lookup (the_assertions, GUINT_TO_POINTER (object));
730 if (cert != NULL) {
731 for (i = 0; i < count; i++) {
732 rv = fill_certificate_attribute (template + i, cert);
733 if (rv != CKR_OK)
734 template[i].ulValueLen = (CK_ULONG)-1;
735 if (ret != CKR_OK)
736 ret = rv;
738 } else if (assertion != NULL) {
739 for (i = 0; i < count; i++) {
740 rv = fill_assertion_attribute (template + i, assertion);
741 if (rv != CKR_OK)
742 template[i].ulValueLen = (CK_ULONG)-1;
743 if (ret != CKR_OK)
744 ret = rv;
746 } else {
747 ret = CKR_OBJECT_HANDLE_INVALID;
750 return ret;
753 CK_RV
754 mock_readonly_C_SetAttributeValue (CK_SESSION_HANDLE session,
755 CK_OBJECT_HANDLE object,
756 CK_ATTRIBUTE_PTR template,
757 CK_ULONG count)
759 Session *sess;
761 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
762 g_return_val_if_fail (sess, CKR_SESSION_HANDLE_INVALID);
764 return CKR_TOKEN_WRITE_PROTECTED;
767 static gboolean
768 match_object_attributes (CK_SESSION_HANDLE session,
769 CK_ULONG object,
770 CK_ATTRIBUTE_PTR template,
771 CK_ULONG count)
773 CK_ATTRIBUTE_PTR values;
774 gboolean mismatch = FALSE;
775 CK_RV rv;
776 CK_ULONG i;
778 values = g_new0 (CK_ATTRIBUTE, count);
779 for (i = 0; i < count; i++) {
780 values[i].type = template[i].type;
781 if (template[i].ulValueLen != 0 &&
782 template[i].ulValueLen != (CK_ULONG)-1)
783 values[i].pValue = g_malloc (template[i].ulValueLen);
784 values[i].ulValueLen = template[i].ulValueLen;
787 rv = mock_C_GetAttributeValue (session, object, values, count);
789 if (rv == CKR_OK) {
790 for (i = 0; i < count; i++) {
791 if (gcr_comparable_memcmp (values[i].pValue, values[i].ulValueLen,
792 template[i].pValue, template[i].ulValueLen) != 0) {
793 mismatch = TRUE;
794 break;
799 for (i = 0; i < count; i++)
800 g_free (values[i].pValue);
801 g_free (values);
803 if (rv != CKR_OK)
804 return FALSE;
806 return !mismatch;
809 CK_RV
810 mock_C_FindObjectsInit (CK_SESSION_HANDLE session,
811 CK_ATTRIBUTE_PTR template,
812 CK_ULONG count)
814 GList *objects = NULL, *l;
815 Session *sess;
817 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
818 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
820 /* Starting an operation, cancels any previous one */
821 if (sess->operation != 0)
822 sess->operation = 0;
824 sess->operation = OP_FIND;
825 g_list_free (sess->matches);
826 sess->matches = NULL;
828 objects = g_list_concat (objects, g_hash_table_get_keys (the_certificates));
829 objects = g_list_concat (objects, g_hash_table_get_keys (the_assertions));
831 for (l = objects; l != NULL; l = g_list_next (l)) {
832 if (match_object_attributes (session, GPOINTER_TO_UINT (l->data), template, count))
833 sess->matches = g_list_prepend (sess->matches, l->data);
836 g_list_free (objects);
837 return CKR_OK;
840 CK_RV
841 mock_C_FindObjects (CK_SESSION_HANDLE session,
842 CK_OBJECT_HANDLE_PTR object,
843 CK_ULONG max_object_count,
844 CK_ULONG_PTR object_count)
846 Session *sess;
848 g_return_val_if_fail (object, CKR_ARGUMENTS_BAD);
849 g_return_val_if_fail (object_count, CKR_ARGUMENTS_BAD);
850 g_return_val_if_fail (max_object_count != 0, CKR_ARGUMENTS_BAD);
852 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
853 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
854 g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
856 *object_count = 0;
857 while (max_object_count > 0 && sess->matches)
859 *object = GPOINTER_TO_UINT (sess->matches->data);
860 ++object;
861 --max_object_count;
862 ++(*object_count);
863 sess->matches = g_list_remove (sess->matches, sess->matches->data);
866 return CKR_OK;
869 CK_RV
870 mock_C_FindObjectsFinal (CK_SESSION_HANDLE session)
872 Session *sess;
874 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
875 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
876 g_return_val_if_fail (sess->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
878 sess->operation = 0;
879 g_list_free (sess->matches);
880 sess->matches = NULL;
882 return CKR_OK;
885 CK_RV
886 mock_no_mechanisms_C_EncryptInit (CK_SESSION_HANDLE session,
887 CK_MECHANISM_PTR mechanism,
888 CK_OBJECT_HANDLE key)
890 Session *sess;
892 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
893 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
895 return CKR_MECHANISM_INVALID;
898 CK_RV
899 mock_not_initialized_C_Encrypt (CK_SESSION_HANDLE session,
900 CK_BYTE_PTR data,
901 CK_ULONG data_len,
902 CK_BYTE_PTR encrypted_data,
903 CK_ULONG_PTR encrypted_data_len)
905 return CKR_OPERATION_NOT_INITIALIZED;
908 CK_RV
909 mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE session,
910 CK_BYTE_PTR part,
911 CK_ULONG part_len,
912 CK_BYTE_PTR encrypted_part,
913 CK_ULONG_PTR encrypted_part_len)
915 return CKR_FUNCTION_NOT_SUPPORTED;
918 CK_RV
919 mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE session,
920 CK_BYTE_PTR last_encrypted_part,
921 CK_ULONG_PTR last_encrypted_part_len)
923 return CKR_FUNCTION_NOT_SUPPORTED;
926 CK_RV
927 mock_no_mechanisms_C_DecryptInit (CK_SESSION_HANDLE session,
928 CK_MECHANISM_PTR mechanism,
929 CK_OBJECT_HANDLE key)
931 Session *sess;
933 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
934 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
936 return CKR_MECHANISM_INVALID;
939 CK_RV
940 mock_not_initialized_C_Decrypt (CK_SESSION_HANDLE session,
941 CK_BYTE_PTR encrypted_data,
942 CK_ULONG encrypted_data_len,
943 CK_BYTE_PTR data,
944 CK_ULONG_PTR data_len)
946 return CKR_OPERATION_NOT_INITIALIZED;
949 CK_RV
950 mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE session,
951 CK_BYTE_PTR encrypted_part,
952 CK_ULONG encrypted_key_len,
953 CK_BYTE_PTR part,
954 CK_ULONG_PTR part_len)
956 return CKR_FUNCTION_NOT_SUPPORTED;
959 CK_RV
960 mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE session,
961 CK_BYTE_PTR last_part,
962 CK_ULONG_PTR last_part_len)
964 return CKR_FUNCTION_NOT_SUPPORTED;
967 CK_RV
968 mock_unsupported_C_DigestInit (CK_SESSION_HANDLE session,
969 CK_MECHANISM_PTR mechanism)
971 return CKR_FUNCTION_NOT_SUPPORTED;
974 CK_RV
975 mock_unsupported_C_Digest (CK_SESSION_HANDLE session,
976 CK_BYTE_PTR data,
977 CK_ULONG data_len,
978 CK_BYTE_PTR digest,
979 CK_ULONG_PTR digest_len)
981 return CKR_FUNCTION_NOT_SUPPORTED;
984 CK_RV
985 mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE session,
986 CK_BYTE_PTR part,
987 CK_ULONG part_len)
989 return CKR_FUNCTION_NOT_SUPPORTED;
992 CK_RV
993 mock_unsupported_C_DigestKey (CK_SESSION_HANDLE session,
994 CK_OBJECT_HANDLE key)
996 return CKR_FUNCTION_NOT_SUPPORTED;
999 CK_RV
1000 mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE session,
1001 CK_BYTE_PTR digest,
1002 CK_ULONG_PTR digest_len)
1004 return CKR_FUNCTION_NOT_SUPPORTED;
1007 CK_RV
1008 mock_no_mechanisms_C_SignInit (CK_SESSION_HANDLE session,
1009 CK_MECHANISM_PTR mechanism,
1010 CK_OBJECT_HANDLE key)
1012 Session *sess;
1014 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1015 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1017 return CKR_MECHANISM_INVALID;
1020 CK_RV
1021 mock_not_initialized_C_Sign (CK_SESSION_HANDLE session,
1022 CK_BYTE_PTR data,
1023 CK_ULONG data_len,
1024 CK_BYTE_PTR signature,
1025 CK_ULONG_PTR signature_len)
1027 return CKR_OPERATION_NOT_INITIALIZED;
1030 CK_RV
1031 mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE session,
1032 CK_BYTE_PTR part,
1033 CK_ULONG part_len)
1035 return CKR_FUNCTION_NOT_SUPPORTED;
1038 CK_RV
1039 mock_unsupported_C_SignFinal (CK_SESSION_HANDLE session,
1040 CK_BYTE_PTR signature,
1041 CK_ULONG_PTR signature_len)
1043 return CKR_FUNCTION_NOT_SUPPORTED;
1046 CK_RV
1047 mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE session,
1048 CK_MECHANISM_PTR mechanism,
1049 CK_OBJECT_HANDLE key)
1051 return CKR_FUNCTION_NOT_SUPPORTED;
1054 CK_RV
1055 mock_unsupported_C_SignRecover (CK_SESSION_HANDLE session,
1056 CK_BYTE_PTR data,
1057 CK_ULONG data_len,
1058 CK_BYTE_PTR signature,
1059 CK_ULONG_PTR signature_len)
1061 return CKR_FUNCTION_NOT_SUPPORTED;
1064 CK_RV
1065 mock_no_mechanisms_C_VerifyInit (CK_SESSION_HANDLE session,
1066 CK_MECHANISM_PTR mechanism,
1067 CK_OBJECT_HANDLE key)
1069 Session *sess;
1071 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1072 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1074 return CKR_MECHANISM_INVALID;
1077 CK_RV
1078 mock_not_initialized_C_Verify (CK_SESSION_HANDLE session,
1079 CK_BYTE_PTR data,
1080 CK_ULONG data_len,
1081 CK_BYTE_PTR signature,
1082 CK_ULONG signature_len)
1084 return CKR_OPERATION_NOT_INITIALIZED;
1087 CK_RV
1088 mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE session,
1089 CK_BYTE_PTR part,
1090 CK_ULONG part_len)
1092 return CKR_FUNCTION_NOT_SUPPORTED;
1095 CK_RV
1096 mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE session,
1097 CK_BYTE_PTR signature,
1098 CK_ULONG signature_len)
1100 return CKR_FUNCTION_NOT_SUPPORTED;
1103 CK_RV
1104 mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE session,
1105 CK_MECHANISM_PTR mechanism,
1106 CK_OBJECT_HANDLE key)
1108 return CKR_FUNCTION_NOT_SUPPORTED;
1111 CK_RV
1112 mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE session,
1113 CK_BYTE_PTR signature,
1114 CK_ULONG signature_len,
1115 CK_BYTE_PTR data,
1116 CK_ULONG_PTR data_len)
1118 return CKR_FUNCTION_NOT_SUPPORTED;
1121 CK_RV
1122 mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE session,
1123 CK_BYTE_PTR part,
1124 CK_ULONG part_len,
1125 CK_BYTE_PTR encrypted_part,
1126 CK_ULONG_PTR encrypted_key_len)
1128 return CKR_FUNCTION_NOT_SUPPORTED;
1131 CK_RV
1132 mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE session,
1133 CK_BYTE_PTR encrypted_part,
1134 CK_ULONG encrypted_key_len,
1135 CK_BYTE_PTR part,
1136 CK_ULONG_PTR part_len)
1138 return CKR_FUNCTION_NOT_SUPPORTED;
1141 CK_RV
1142 mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE session,
1143 CK_BYTE_PTR part,
1144 CK_ULONG part_len,
1145 CK_BYTE_PTR encrypted_part,
1146 CK_ULONG_PTR encrypted_key_len)
1148 return CKR_FUNCTION_NOT_SUPPORTED;
1151 CK_RV
1152 mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE session,
1153 CK_BYTE_PTR encrypted_part,
1154 CK_ULONG encrypted_key_len,
1155 CK_BYTE_PTR part,
1156 CK_ULONG_PTR part_len)
1158 return CKR_FUNCTION_NOT_SUPPORTED;
1161 CK_RV
1162 mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE session,
1163 CK_MECHANISM_PTR mechanism,
1164 CK_ATTRIBUTE_PTR template,
1165 CK_ULONG count,
1166 CK_OBJECT_HANDLE_PTR key)
1168 return CKR_FUNCTION_NOT_SUPPORTED;
1171 CK_RV
1172 mock_no_mechanisms_C_GenerateKeyPair (CK_SESSION_HANDLE session,
1173 CK_MECHANISM_PTR mechanism,
1174 CK_ATTRIBUTE_PTR public_key_template,
1175 CK_ULONG public_key_attribute_count,
1176 CK_ATTRIBUTE_PTR private_key_template,
1177 CK_ULONG private_key_attribute_count,
1178 CK_OBJECT_HANDLE_PTR public_key,
1179 CK_OBJECT_HANDLE_PTR private_key)
1181 Session *sess;
1183 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1184 g_return_val_if_fail (public_key_template, CKR_TEMPLATE_INCOMPLETE);
1185 g_return_val_if_fail (public_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1186 g_return_val_if_fail (private_key_template, CKR_TEMPLATE_INCOMPLETE);
1187 g_return_val_if_fail (private_key_attribute_count, CKR_TEMPLATE_INCOMPLETE);
1188 g_return_val_if_fail (public_key, CKR_ARGUMENTS_BAD);
1189 g_return_val_if_fail (private_key, CKR_ARGUMENTS_BAD);
1191 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1192 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1194 return CKR_MECHANISM_INVALID;
1197 CK_RV
1198 mock_no_mechanisms_C_WrapKey (CK_SESSION_HANDLE session,
1199 CK_MECHANISM_PTR mechanism,
1200 CK_OBJECT_HANDLE wrapping_key,
1201 CK_OBJECT_HANDLE key,
1202 CK_BYTE_PTR wrapped_key,
1203 CK_ULONG_PTR wrapped_key_len)
1205 Session *sess;
1207 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1208 g_return_val_if_fail (wrapping_key, CKR_OBJECT_HANDLE_INVALID);
1209 g_return_val_if_fail (key, CKR_OBJECT_HANDLE_INVALID);
1210 g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1212 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1213 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1215 return CKR_MECHANISM_INVALID;
1218 CK_RV
1219 mock_no_mechanisms_C_UnwrapKey (CK_SESSION_HANDLE session,
1220 CK_MECHANISM_PTR mechanism,
1221 CK_OBJECT_HANDLE unwrapping_key,
1222 CK_BYTE_PTR wrapped_key,
1223 CK_ULONG wrapped_key_len,
1224 CK_ATTRIBUTE_PTR template,
1225 CK_ULONG count,
1226 CK_OBJECT_HANDLE_PTR key)
1228 Session *sess;
1230 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1231 g_return_val_if_fail (unwrapping_key, CKR_WRAPPING_KEY_HANDLE_INVALID);
1232 g_return_val_if_fail (wrapped_key, CKR_WRAPPED_KEY_INVALID);
1233 g_return_val_if_fail (wrapped_key_len, CKR_WRAPPED_KEY_LEN_RANGE);
1234 g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1235 g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1236 g_return_val_if_fail (count, CKR_TEMPLATE_INCONSISTENT);
1238 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1239 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1241 return CKR_MECHANISM_INVALID;
1244 CK_RV
1245 mock_no_mechanisms_C_DeriveKey (CK_SESSION_HANDLE session,
1246 CK_MECHANISM_PTR mechanism,
1247 CK_OBJECT_HANDLE base_key,
1248 CK_ATTRIBUTE_PTR template,
1249 CK_ULONG count,
1250 CK_OBJECT_HANDLE_PTR key)
1252 Session *sess;
1254 g_return_val_if_fail (mechanism, CKR_MECHANISM_INVALID);
1255 g_return_val_if_fail (count, CKR_TEMPLATE_INCOMPLETE);
1256 g_return_val_if_fail (template, CKR_TEMPLATE_INCOMPLETE);
1257 g_return_val_if_fail (key, CKR_ARGUMENTS_BAD);
1259 sess = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (session));
1260 g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
1262 return CKR_MECHANISM_INVALID;
1265 CK_RV
1266 mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE session,
1267 CK_BYTE_PTR pSeed,
1268 CK_ULONG seed_len)
1270 return CKR_FUNCTION_NOT_SUPPORTED;
1273 CK_RV
1274 mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE session,
1275 CK_BYTE_PTR random_data,
1276 CK_ULONG random_len)
1278 return CKR_FUNCTION_NOT_SUPPORTED;
1281 CK_FUNCTION_LIST mock_default_functions = {
1282 { 2, 11 }, /* version */
1283 mock_C_Initialize,
1284 mock_C_Finalize,
1285 mock_C_GetInfo,
1286 mock_C_GetFunctionList,
1287 mock_C_GetSlotList,
1288 mock_C_GetSlotInfo,
1289 mock_C_GetTokenInfo,
1290 mock_C_GetMechanismList,
1291 mock_C_GetMechanismInfo,
1292 mock_unsupported_C_InitToken,
1293 mock_unsupported_C_InitPIN,
1294 mock_unsupported_C_SetPIN,
1295 mock_C_OpenSession,
1296 mock_C_CloseSession,
1297 mock_C_CloseAllSessions,
1298 mock_C_GetSessionInfo,
1299 mock_unsupported_C_GetOperationState,
1300 mock_unsupported_C_SetOperationState,
1301 mock_unsupported_C_Login,
1302 mock_unsupported_C_Logout,
1303 mock_readonly_C_CreateObject,
1304 mock_unsupported_C_CopyObject,
1305 mock_readonly_C_DestroyObject,
1306 mock_unsupported_C_GetObjectSize,
1307 mock_C_GetAttributeValue,
1308 mock_readonly_C_SetAttributeValue,
1309 mock_C_FindObjectsInit,
1310 mock_C_FindObjects,
1311 mock_C_FindObjectsFinal,
1312 mock_no_mechanisms_C_EncryptInit,
1313 mock_not_initialized_C_Encrypt,
1314 mock_unsupported_C_EncryptUpdate,
1315 mock_unsupported_C_EncryptFinal,
1316 mock_no_mechanisms_C_DecryptInit,
1317 mock_not_initialized_C_Decrypt,
1318 mock_unsupported_C_DecryptUpdate,
1319 mock_unsupported_C_DecryptFinal,
1320 mock_unsupported_C_DigestInit,
1321 mock_unsupported_C_Digest,
1322 mock_unsupported_C_DigestUpdate,
1323 mock_unsupported_C_DigestKey,
1324 mock_unsupported_C_DigestFinal,
1325 mock_no_mechanisms_C_SignInit,
1326 mock_not_initialized_C_Sign,
1327 mock_unsupported_C_SignUpdate,
1328 mock_unsupported_C_SignFinal,
1329 mock_unsupported_C_SignRecoverInit,
1330 mock_unsupported_C_SignRecover,
1331 mock_no_mechanisms_C_VerifyInit,
1332 mock_not_initialized_C_Verify,
1333 mock_unsupported_C_VerifyUpdate,
1334 mock_unsupported_C_VerifyFinal,
1335 mock_unsupported_C_VerifyRecoverInit,
1336 mock_unsupported_C_VerifyRecover,
1337 mock_unsupported_C_DigestEncryptUpdate,
1338 mock_unsupported_C_DecryptDigestUpdate,
1339 mock_unsupported_C_SignEncryptUpdate,
1340 mock_unsupported_C_DecryptVerifyUpdate,
1341 mock_unsupported_C_GenerateKey,
1342 mock_no_mechanisms_C_GenerateKeyPair,
1343 mock_no_mechanisms_C_WrapKey,
1344 mock_no_mechanisms_C_UnwrapKey,
1345 mock_no_mechanisms_C_DeriveKey,
1346 mock_unsupported_C_SeedRandom,
1347 mock_unsupported_C_GenerateRandom,
1348 mock_C_GetFunctionStatus,
1349 mock_C_CancelFunction,
1350 mock_unsupported_C_WaitForSlotEvent