summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-05-02 15:36:56 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-05-03 13:02:39 +0200
commitc2962ab4e236819707939557351dea7907356a62 (patch)
tree044fdff4fa53fac9cc64d5e7aac301aeb8efa7a2
parent7b0168dfa69180ea42b6fb8c1fde3a49dcb7031c (diff)
downloadgnutls-c2962ab4e236819707939557351dea7907356a62.tar.gz
tests: added a basic PKCS#11 mock module
This is used to test gnutls_pkcs11_obj_get_exts(), gnutls_x509_crt_import_url(), and gnutls_pkcs11_get_raw_issuer() with the GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT flag.
-rw-r--r--tests/Makefile.am23
-rw-r--r--tests/pkcs11/pkcs11-cert-import-url-exts.c135
-rw-r--r--tests/pkcs11/pkcs11-get-exts.c150
-rw-r--r--tests/pkcs11/pkcs11-get-raw-issuer-exts.c145
-rw-r--r--tests/pkcs11/pkcs11-mock.c2639
-rw-r--r--tests/pkcs11/pkcs11-mock.h92
6 files changed, 3184 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1f87c7960e..391ae2e93e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -39,6 +39,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h test-chains.h \
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
AM_CPPFLAGS = \
+ $(P11_KIT_CFLAGS) \
-I$(top_srcdir)/lib/includes \
-I$(top_builddir)/lib/includes \
-I$(top_srcdir)/libdane/includes \
@@ -62,6 +63,8 @@ endif
noinst_LTLIBRARIES = libutils.la
libutils_la_SOURCES = utils.h utils.c
+pkglib_LTLIBRARIES =
+
ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \
mpi certificate_set_x509_crl dn parse_ca moredn record-sizes \
hostname-check cve-2008-4989 pkcs12_s2k chainverify record-sizes-range \
@@ -94,6 +97,25 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \
mini_dtls_pthread_LDADD = $(LDADD) -lpthread
+if ENABLE_PKCS11
+if !WINDOWS
+pkglib_LTLIBRARIES += libpkcs11mock1.la
+libpkcs11mock1_la_SOURCES = pkcs11/pkcs11-mock.c pkcs11/pkcs11-mock.h
+libpkcs11mock1_la_LDFLAGS = -module -no-undefined -avoid-version
+
+pkcs11_cert_import_url_exts_SOURCES = pkcs11/pkcs11-cert-import-url-exts.c
+pkcs11_cert_import_url_exts_DEPENDENCIES = libpkcs11mock1.la libutils.la
+
+pkcs11_get_exts_SOURCES = pkcs11/pkcs11-get-exts.c
+pkcs11_get_exts_DEPENDENCIES = libpkcs11mock1.la libutils.la
+
+pkcs11_get_raw_issuer_exts_SOURCES = pkcs11/pkcs11-get-raw-issuer-exts.c
+pkcs11_get_raw_issuer_exts_DEPENDENCIES = libpkcs11mock1.la libutils.la
+
+ctests += pkcs11-cert-import-url-exts pkcs11-get-exts pkcs11-get-raw-issuer-exts
+endif
+endif
+
if ENABLE_OCSP
ctests += ocsp
endif
@@ -165,6 +187,7 @@ TESTS = $(ctests) $(dist_check_SCRIPTS)
TESTS_ENVIRONMENT = \
LC_ALL="C" \
CAFILE=$(srcdir)/cert-tests/ca-certs.pem \
+ P11MOCKLIB1=$(abs_builddir)/.libs/libpkcs11mock1.so \
PKCS12_MANY_CERTS_FILE=$(srcdir)/pkcs12-decode/pkcs12_5certs.p12 \
PKCS12FILE=$(srcdir)/pkcs12-decode/client.p12 \
PKCS12PASSWORD=foobar \
diff --git a/tests/pkcs11/pkcs11-cert-import-url-exts.c b/tests/pkcs11/pkcs11-cert-import-url-exts.c
new file mode 100644
index 0000000000..0846c3153b
--- /dev/null
+++ b/tests/pkcs11/pkcs11-cert-import-url-exts.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/x509-ext.h>
+
+#include "utils.h"
+
+/* Tests the certificate extension override in "trusted" PKCS#11 modules */
+
+#ifdef _WIN32
+# define P11LIB "libpkcs11mock1.dll"
+#else
+# define P11LIB "libpkcs11mock1.so"
+#endif
+
+static time_t mytime(time_t * t)
+{
+ time_t then = 1424466893;
+
+ if (t)
+ *t = then;
+
+ return then;
+}
+
+void doit(void)
+{
+ int ret;
+ gnutls_x509_crt_t crt, ocrt;
+ unsigned keyusage;
+ const char *lib;
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ lib = getenv("P11MOCKLIB1");
+ if (lib == NULL)
+ lib = P11LIB;
+
+ gnutls_global_set_time_function(mytime);
+ if (debug) {
+ gnutls_global_set_log_level(4711);
+ success("loading lib %s\n", lib);
+ }
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_add_provider(lib, "trusted");
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(gnutls_x509_crt_init(&crt)>=0);
+ assert(gnutls_x509_crt_init(&ocrt)>=0);
+
+ /* check high level certificate functions */
+ ret = gnutls_x509_crt_import_url(crt, "pkcs11:type=cert;object=cert1", 0);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_import_url(ocrt, "pkcs11:type=cert;object=cert1", GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_get_ca_status(ocrt, NULL);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (ret == 0) {
+ fail("overriden cert is not a CA!\n");
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_get_key_usage(ocrt, &keyusage, NULL);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (keyusage != (GNUTLS_KEY_KEY_ENCIPHERMENT|GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_KEY_CERT_SIGN)) {
+ fail("Extension does not have the expected key usage!\n");
+ }
+
+ gnutls_x509_crt_deinit(crt);
+ gnutls_x509_crt_deinit(ocrt);
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_global_deinit();
+}
diff --git a/tests/pkcs11/pkcs11-get-exts.c b/tests/pkcs11/pkcs11-get-exts.c
new file mode 100644
index 0000000000..1d236a6b3d
--- /dev/null
+++ b/tests/pkcs11/pkcs11-get-exts.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/x509-ext.h>
+
+#include "utils.h"
+
+/* Tests the gnutls_pkcs11_obj_get_exts API */
+
+#ifdef _WIN32
+# define P11LIB "libpkcs11mock1.dll"
+#else
+# define P11LIB "libpkcs11mock1.so"
+#endif
+
+void doit(void)
+{
+ int ret;
+ const char *lib;
+ gnutls_x509_ext_st *exts;
+ unsigned int exts_size, i;
+ gnutls_pkcs11_obj_t obj;
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ lib = getenv("P11MOCKLIB1");
+ if (lib == NULL)
+ lib = P11LIB;
+
+ if (debug) {
+ gnutls_global_set_log_level(4711);
+ success("loading lib %s\n", lib);
+ }
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_add_provider(lib, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(gnutls_pkcs11_obj_init(&obj)>=0);
+
+ /* check extensions */
+ ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:type=cert;object=cert1", 0);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_obj_get_exts(obj, &exts, &exts_size, 0);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (exts_size != 2) {
+ fail("the expected extensions were not found (found %d)!\n", exts_size);
+ exit(1);
+ }
+
+ if (strcmp(exts[0].oid, "2.5.29.19") != 0) {
+ fail("Found OID for %d: %s\n", 0, exts[0].oid);
+ }
+
+ {
+ unsigned ca;
+ int pathlen;
+ ret = gnutls_x509_ext_import_basic_constraints(&exts[0].data, &ca, &pathlen);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug)
+ success("ca: %d/%d\n", ca, pathlen);
+ if (ca != 1) {
+ fail("Extension does not set the CA constraint!\n");
+ }
+ }
+
+ if (strcmp(exts[1].oid, "2.5.29.15") != 0) {
+ fail("Found OID for %d: %s\n", 1, exts[1].oid);
+ }
+
+ {
+ unsigned keyusage;
+ ret = gnutls_x509_ext_import_key_usage(&exts[1].data, &keyusage);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug)
+ success("usage: %x\n", keyusage);
+ if (keyusage != (GNUTLS_KEY_KEY_ENCIPHERMENT|GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_KEY_CERT_SIGN)) {
+ fail("Extension does not have the expected key usage!\n");
+ }
+ }
+
+ for (i=0;i<exts_size;i++)
+ gnutls_x509_ext_deinit(&exts[i]);
+ gnutls_free(exts);
+
+ gnutls_pkcs11_obj_deinit(obj);
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_global_deinit();
+}
diff --git a/tests/pkcs11/pkcs11-get-raw-issuer-exts.c b/tests/pkcs11/pkcs11-get-raw-issuer-exts.c
new file mode 100644
index 0000000000..7714db51eb
--- /dev/null
+++ b/tests/pkcs11/pkcs11-get-raw-issuer-exts.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/x509-ext.h>
+
+#include "utils.h"
+
+/* Tests the certificate extension override in "trusted" PKCS#11 modules
+ * when used with gnutls_pkcs11_get_raw_issuer().
+ */
+
+#ifdef _WIN32
+# define P11LIB "libpkcs11mock1.dll"
+#else
+# define P11LIB "libpkcs11mock1.so"
+#endif
+
+static time_t mytime(time_t * t)
+{
+ time_t then = 1424466893;
+
+ if (t)
+ *t = then;
+
+ return then;
+}
+
+void doit(void)
+{
+ int ret;
+ gnutls_x509_crt_t crt, ocrt;
+ unsigned keyusage;
+ const char *lib;
+ gnutls_datum_t issuer = {NULL, 0};
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ lib = getenv("P11MOCKLIB1");
+ if (lib == NULL)
+ lib = P11LIB;
+
+ gnutls_global_set_time_function(mytime);
+ if (debug) {
+ gnutls_global_set_log_level(4711);
+ success("loading lib %s\n", lib);
+ }
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_add_provider(lib, "trusted");
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(gnutls_x509_crt_init(&crt)>=0);
+ assert(gnutls_x509_crt_init(&ocrt)>=0);
+
+ /* check high level certificate functions */
+ ret = gnutls_x509_crt_import_url(crt, "pkcs11:type=cert;object=cert1", 0);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_get_raw_issuer("pkcs11:", crt, &issuer, GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_import(ocrt, &issuer, GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_get_ca_status(ocrt, NULL);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (ret == 0) {
+ fail("overriden cert is not a CA!\n");
+ exit(1);
+ }
+
+ ret = gnutls_x509_crt_get_key_usage(ocrt, &keyusage, NULL);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (keyusage != (GNUTLS_KEY_KEY_ENCIPHERMENT|GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_KEY_CERT_SIGN)) {
+ fail("Extension does not have the expected key usage!\n");
+ }
+
+ gnutls_x509_crt_deinit(crt);
+ gnutls_x509_crt_deinit(ocrt);
+ gnutls_free(issuer.data);
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_global_deinit();
+}
diff --git a/tests/pkcs11/pkcs11-mock.c b/tests/pkcs11/pkcs11-mock.c
new file mode 100644
index 0000000000..c10ccc1185
--- /dev/null
+++ b/tests/pkcs11/pkcs11-mock.c
@@ -0,0 +1,2639 @@
+/*
+ * PKCS11-MOCK - PKCS#11 mock module
+ * Copyright (c) 2015 JWC s.r.o. <http://www.jwc.sk>
+ * Author: Jaroslav Imrich <jimrich@jimrich.sk>
+ *
+ * Licensing for open source projects:
+ * PKCS11-MOCK is available under the terms of the GNU Affero General
+ * Public License version 3 as published by the Free Software Foundation.
+ * Please see <http://www.gnu.org/licenses/agpl-3.0.html> for more details.
+ *
+ * Licensing for other types of projects:
+ * PKCS11-MOCK is available under the terms of flexible commercial license.
+ * Please contact JWC s.r.o. at <info@pkcs11interop.net> for more details.
+ */
+
+
+#include "pkcs11-mock.h"
+#include <stdlib.h>
+
+/* This is a very basic mock PKCS #11 module that will return a given fixed
+ * certificate, and public key for all searches. It will also provide a
+ * CKO_X_CERTIFICATE_EXTENSION so that it can be used as a p11-kit trust
+ * module. */
+
+const char mock_certificate[] =
+ "\x30\x82\x03\x97\x30\x82\x02\x4f\xa0\x03\x02\x01\x02\x02\x04\x4d"
+ "\xa7\x54\x21\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b"
+ "\x05\x00\x30\x32\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42"
+ "\x45\x31\x0f\x30\x0d\x06\x03\x55\x04\x0a\x13\x06\x47\x6e\x75\x54"
+ "\x4c\x53\x31\x12\x30\x10\x06\x03\x55\x04\x03\x13\x09\x6c\x6f\x63"
+ "\x61\x6c\x68\x6f\x73\x74\x30\x1e\x17\x0d\x31\x31\x30\x34\x31\x34"
+ "\x32\x30\x30\x38\x30\x32\x5a\x17\x0d\x33\x38\x30\x38\x32\x39\x32"
+ "\x30\x30\x38\x30\x34\x5a\x30\x32\x31\x0b\x30\x09\x06\x03\x55\x04"
+ "\x06\x13\x02\x42\x45\x31\x0f\x30\x0d\x06\x03\x55\x04\x0a\x13\x06"
+ "\x47\x6e\x75\x54\x4c\x53\x31\x12\x30\x10\x06\x03\x55\x04\x03\x13"
+ "\x09\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74\x30\x82\x01\x52\x30\x0d"
+ "\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01"
+ "\x3f\x00\x30\x82\x01\x3a\x02\x82\x01\x31\x00\xdd\xcf\x97\xd2\xa5"
+ "\x1d\x95\xdd\x86\x18\xd8\xc4\xb9\xad\xa6\x0c\xb4\x9d\xb6\xdc\xfa"
+ "\xdc\x21\xe1\x3a\x62\x34\x07\xe8\x33\xb2\xe8\x97\xee\x2c\x41\xd2"
+ "\x12\xf1\x5f\xed\xe4\x76\xff\x65\x26\x1e\x0c\xc7\x41\x15\x69\x5f"
+ "\x0d\xf9\xad\x89\x14\x8d\xea\xd7\x16\x52\x9a\x47\xc1\xbb\x00\x02"
+ "\xe4\x88\x45\x73\x78\xa4\xae\xdb\x38\xc3\xc6\x07\xd2\x64\x0e\x87"
+ "\xed\x74\x8c\x6b\xc4\xc0\x02\x50\x7c\x4e\xa6\xd1\x58\xe9\xe5\x13"
+ "\x09\xa9\xdb\x5a\xea\xeb\x0f\x06\x80\x5c\x09\xef\x94\xc8\xe9\xfb"
+ "\x37\x2e\x75\xe1\xac\x93\xad\x9b\x37\x13\x4b\x66\x3a\x76\x33\xd8"
+ "\xc4\xd7\x4c\xfb\x61\xc8\x92\x21\x07\xfc\xdf\xa9\x88\x54\xe4\xa3"
+ "\xa9\x47\xd2\x6c\xb8\xe3\x39\x89\x11\x88\x38\x2d\xa2\xdc\x3e\x5e"
+ "\x4a\xa9\xa4\x8e\xd5\x1f\xb2\xd0\xdd\x41\x3c\xda\x10\x68\x9e\x47"
+ "\x1b\x65\x02\xa2\xc5\x28\x73\x02\x83\x03\x09\xfd\xf5\x29\x7e\x97"
+ "\xdc\x2a\x4e\x4b\xaa\x79\x46\x46\x70\x86\x1b\x9b\xb8\xf6\x8a\xbe"
+ "\x29\x87\x7d\x5f\xda\xa5\x97\x6b\xef\xc8\x43\x09\x43\xe2\x1f\x8a"
+ "\x16\x7e\x1d\x50\x5d\xf5\xda\x02\xee\xf2\xc3\x2a\x48\xe6\x6b\x30"
+ "\xea\x02\xd7\xef\xac\x8b\x0c\xb8\xc1\x85\xd8\xbf\x7c\x85\xa8\x1e"
+ "\x83\xbe\x5c\x26\x2e\x79\x7b\x47\xf5\x4a\x3f\x66\x62\x92\xfd\x41"
+ "\x20\xb6\x2c\x00\xf0\x52\xca\x26\x06\x2d\x7c\xcf\x7a\x50\x7d\x0f"
+ "\xcb\xdd\x97\x20\xc8\x6f\xe4\xe0\x50\xf4\xe3\x02\x03\x01\x00\x01"
+ "\xa3\x55\x30\x53\x30\x0c\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x02"
+ "\x30\x00\x30\x13\x06\x03\x55\x1d\x25\x04\x0c\x30\x0a\x06\x08\x2b"
+ "\x06\x01\x05\x05\x07\x03\x01\x30\x0f\x06\x03\x55\x1d\x0f\x01\x01"
+ "\xff\x04\x05\x03\x03\x07\xa0\x00\x30\x1d\x06\x03\x55\x1d\x0e\x04"
+ "\x16\x04\x14\x92\x53\xd6\x71\xb9\xf8\x68\xaa\xb3\x53\xf6\x8d\xf5"
+ "\x39\x45\x66\x9c\xa7\xe5\x31\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7"
+ "\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x31\x00\x98\xbf\x48\x89\xc1"
+ "\xe6\xe6\x15\x13\xcc\xfc\xba\xed\xa0\x89\xe5\x86\x45\x30\x73\x68"
+ "\xb2\x79\x1f\x88\x02\x80\xfb\x2d\xc9\xb8\x21\x55\x8d\xc5\xb7\x56"
+ "\x1b\xcf\xc3\x76\xee\xd0\xf0\xd9\x22\x3a\x63\x92\xc5\x04\x86\x70"
+ "\x1e\x42\x33\x2a\x3b\xc4\x14\x08\xc5\x42\x92\x73\x7c\x3e\x39\xc0"
+ "\xee\x34\xc7\x33\x16\x5f\x93\xae\xcf\x1f\x9a\x30\x09\x51\xfe\x2d"
+ "\x94\x9c\x28\xad\x2a\x7e\xe4\x14\x81\x45\x6b\x0d\xd7\x11\x21\xfc"
+ "\xdb\x27\x17\x74\xb4\xcc\x94\x1a\x6e\x9e\x7b\x58\xa9\xe0\x06\x8d"
+ "\xda\x5f\x60\xe1\xb8\x6f\x28\x68\xb6\x58\xbe\xc5\xac\x36\x47\x37"
+ "\xf6\xa8\x38\x74\x23\x81\xf3\x22\xbe\x61\xff\x08\x08\x87\xeb\xc2"
+ "\x8f\x29\x25\x75\x5d\x4c\xeb\xd5\x09\x28\xab\x7b\x99\xf9\x69\x08"
+ "\xa2\xc6\x02\xd2\x2e\xcd\xfa\xf1\x19\xce\x3f\x44\x6a\xa1\x4b\xa8"
+ "\x56\xd5\x11\xae\x44\xe3\x68\x05\x50\x57\x8d\x72\x0f\xc7\x21\xdb"
+ "\x8f\xa3\x50\x78\x5d\x5a\x39\xcb\x90\x3d\x52\x43\x33\xbf\xea\x89"
+ "\x07\x1a\x92\xcc\x85\x27\xa8\x3d\x34\xb8\x5b\x52\xee\xef\x20\xb9"
+ "\xb6\xff\xea\xc5\x90\xd3\x47\xc5\x51\x90\xe2\xe6\x3e\x52\xb9\x1e"
+ "\x79\x18\xbe\xfd\xe2\x24\xbe\x47\x32\x5a\xb0\x03\x6b\xaa\xdb\xc3"
+ "\xdb\xf6\x60\x44\x08\xb6\x2c\x19\x47\xa2\xf0\x43\x7f\xf0\x07\x97"
+ "\x57\xab\xec\xa0\xb8\x6a\x49\xce\x08\xe6\xc3\x4d\xf2\xa4\xe9\xb8"
+ "\x43\xe7\xf0\x84\xd7\x1a\x72\x14\x5d\x82\x1a";
+
+/* ca == true */
+const char mock_cert_ext1[] = "\x30\x0f\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x05\x30\x03\x01\x01\xff";
+/* GNUTLS_KEY_ENCIPHER_ONLY | GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_KEY_CERT_SIGN */
+const char mock_cert_ext2[] = "\x30\x0f\x06\x03\x55\x1d\x0f\x01\x01\xff\x04\x05\x03\x03\x07\x25\x00";
+
+const char mock_pubkey[] =
+ "\x30\x82\x01\x52\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01"
+ "\x01\x05\x00\x03\x82\x01\x3f\x00\x30\x82\x01\x3a\x02\x82\x01\x31"
+ "\x00\xdd\xcf\x97\xd2\xa5\x1d\x95\xdd\x86\x18\xd8\xc4\xb9\xad\xa6"
+ "\x0c\xb4\x9d\xb6\xdc\xfa\xdc\x21\xe1\x3a\x62\x34\x07\xe8\x33\xb2"
+ "\xe8\x97\xee\x2c\x41\xd2\x12\xf1\x5f\xed\xe4\x76\xff\x65\x26\x1e"
+ "\x0c\xc7\x41\x15\x69\x5f\x0d\xf9\xad\x89\x14\x8d\xea\xd7\x16\x52"
+ "\x9a\x47\xc1\xbb\x00\x02\xe4\x88\x45\x73\x78\xa4\xae\xdb\x38\xc3"
+ "\xc6\x07\xd2\x64\x0e\x87\xed\x74\x8c\x6b\xc4\xc0\x02\x50\x7c\x4e"
+ "\xa6\xd1\x58\xe9\xe5\x13\x09\xa9\xdb\x5a\xea\xeb\x0f\x06\x80\x5c"
+ "\x09\xef\x94\xc8\xe9\xfb\x37\x2e\x75\xe1\xac\x93\xad\x9b\x37\x13"
+ "\x4b\x66\x3a\x76\x33\xd8\xc4\xd7\x4c\xfb\x61\xc8\x92\x21\x07\xfc"
+ "\xdf\xa9\x88\x54\xe4\xa3\xa9\x47\xd2\x6c\xb8\xe3\x39\x89\x11\x88"
+ "\x38\x2d\xa2\xdc\x3e\x5e\x4a\xa9\xa4\x8e\xd5\x1f\xb2\xd0\xdd\x41"
+ "\x3c\xda\x10\x68\x9e\x47\x1b\x65\x02\xa2\xc5\x28\x73\x02\x83\x03"
+ "\x09\xfd\xf5\x29\x7e\x97\xdc\x2a\x4e\x4b\xaa\x79\x46\x46\x70\x86"
+ "\x1b\x9b\xb8\xf6\x8a\xbe\x29\x87\x7d\x5f\xda\xa5\x97\x6b\xef\xc8"
+ "\x43\x09\x43\xe2\x1f\x8a\x16\x7e\x1d\x50\x5d\xf5\xda\x02\xee\xf2"
+ "\xc3\x2a\x48\xe6\x6b\x30\xea\x02\xd7\xef\xac\x8b\x0c\xb8\xc1\x85"
+ "\xd8\xbf\x7c\x85\xa8\x1e\x83\xbe\x5c\x26\x2e\x79\x7b\x47\xf5\x4a"
+ "\x3f\x66\x62\x92\xfd\x41\x20\xb6\x2c\x00\xf0\x52\xca\x26\x06\x2d"
+ "\x7c\xcf\x7a\x50\x7d\x0f\xcb\xdd\x97\x20\xc8\x6f\xe4\xe0\x50\xf4"
+ "\xe3\x02\x03\x01\x00\x01";
+
+CK_BBOOL pkcs11_mock_initialized = CK_FALSE;
+CK_BBOOL pkcs11_mock_session_opened = CK_FALSE;
+
+static session_ptr_st *mock_session = NULL;
+
+CK_FUNCTION_LIST pkcs11_mock_functions =
+{
+ {2, 20},
+ &C_Initialize,
+ &C_Finalize,
+ &C_GetInfo,
+ &C_GetFunctionList,
+ &C_GetSlotList,
+ &C_GetSlotInfo,
+ &C_GetTokenInfo,
+ &C_GetMechanismList,
+ &C_GetMechanismInfo,
+ &C_InitToken,
+ &C_InitPIN,
+ &C_SetPIN,
+ &C_OpenSession,
+ &C_CloseSession,
+ &C_CloseAllSessions,
+ &C_GetSessionInfo,
+ &C_GetOperationState,
+ &C_SetOperationState,
+ &C_Login,
+ &C_Logout,
+ &C_CreateObject,
+ &C_CopyObject,
+ &C_DestroyObject,
+ &C_GetObjectSize,
+ &C_GetAttributeValue,
+ &C_SetAttributeValue,
+ &C_FindObjectsInit,
+ &C_FindObjects,
+ &C_FindObjectsFinal,
+ &C_EncryptInit,
+ &C_Encrypt,
+ &C_EncryptUpdate,
+ &C_EncryptFinal,
+ &C_DecryptInit,
+ &C_Decrypt,
+ &C_DecryptUpdate,
+ &C_DecryptFinal,
+ &C_DigestInit,
+ &C_Digest,
+ &C_DigestUpdate,
+ &C_DigestKey,
+ &C_DigestFinal,
+ &C_SignInit,
+ &C_Sign,
+ &C_SignUpdate,
+ &C_SignFinal,
+ &C_SignRecoverInit,
+ &C_SignRecover,
+ &C_VerifyInit,
+ &C_Verify,
+ &C_VerifyUpdate,
+ &C_VerifyFinal,
+ &C_VerifyRecoverInit,
+ &C_VerifyRecover,
+ &C_DigestEncryptUpdate,
+ &C_DecryptDigestUpdate,
+ &C_SignEncryptUpdate,
+ &C_DecryptVerifyUpdate,
+ &C_GenerateKey,
+ &C_GenerateKeyPair,
+ &C_WrapKey,
+ &C_UnwrapKey,
+ &C_DeriveKey,
+ &C_SeedRandom,
+ &C_GenerateRandom,
+ &C_GetFunctionStatus,
+ &C_CancelFunction,
+ &C_WaitForSlotEvent
+};
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs)
+{
+ if (CK_TRUE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+
+ IGNORE(pInitArgs);
+
+ pkcs11_mock_initialized = CK_TRUE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pReserved)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ IGNORE(pReserved);
+
+ pkcs11_mock_initialized = CK_FALSE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ pInfo->cryptokiVersion.major = 0x02;
+ pInfo->cryptokiVersion.minor = 0x14;
+ memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
+ memcpy(pInfo->manufacturerID, PKCS11_MOCK_CK_INFO_MANUFACTURER_ID, strlen(PKCS11_MOCK_CK_INFO_MANUFACTURER_ID));
+ pInfo->flags = 0;
+ memset(pInfo->libraryDescription, ' ', sizeof(pInfo->libraryDescription));
+ memcpy(pInfo->libraryDescription, PKCS11_MOCK_CK_INFO_LIBRARY_DESCRIPTION, strlen(PKCS11_MOCK_CK_INFO_LIBRARY_DESCRIPTION));
+ pInfo->libraryVersion.major = 0x01;
+ pInfo->libraryVersion.minor = 0x00;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
+{
+ if (NULL == ppFunctionList)
+ return CKR_ARGUMENTS_BAD;
+
+ *ppFunctionList = &pkcs11_mock_functions;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ IGNORE(tokenPresent);
+
+ if (NULL == pulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSlotList)
+ {
+ *pulCount = 1;
+ }
+ else
+ {
+ if (0 == *pulCount)
+ return CKR_BUFFER_TOO_SMALL;
+
+ pSlotList[0] = PKCS11_MOCK_CK_SLOT_ID;
+ *pulCount = 1;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ memset(pInfo->slotDescription, ' ', sizeof(pInfo->slotDescription));
+ memcpy(pInfo->slotDescription, PKCS11_MOCK_CK_SLOT_INFO_SLOT_DESCRIPTION, strlen(PKCS11_MOCK_CK_SLOT_INFO_SLOT_DESCRIPTION));
+ memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
+ memcpy(pInfo->manufacturerID, PKCS11_MOCK_CK_SLOT_INFO_MANUFACTURER_ID, strlen(PKCS11_MOCK_CK_SLOT_INFO_MANUFACTURER_ID));
+ pInfo->flags = CKF_TOKEN_PRESENT;
+ pInfo->hardwareVersion.major = 0x01;
+ pInfo->hardwareVersion.minor = 0x00;
+ pInfo->firmwareVersion.major = 0x01;
+ pInfo->firmwareVersion.minor = 0x00;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ memset(pInfo->label, ' ', sizeof(pInfo->label));
+ memcpy(pInfo->label, PKCS11_MOCK_CK_TOKEN_INFO_LABEL, strlen(PKCS11_MOCK_CK_TOKEN_INFO_LABEL));
+ memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
+ memcpy(pInfo->manufacturerID, PKCS11_MOCK_CK_TOKEN_INFO_MANUFACTURER_ID, strlen(PKCS11_MOCK_CK_TOKEN_INFO_MANUFACTURER_ID));
+ memset(pInfo->model, ' ', sizeof(pInfo->model));
+ memcpy(pInfo->model, PKCS11_MOCK_CK_TOKEN_INFO_MODEL, strlen(PKCS11_MOCK_CK_TOKEN_INFO_MODEL));
+ memset(pInfo->serialNumber, ' ', sizeof(pInfo->serialNumber));
+ memcpy(pInfo->serialNumber, PKCS11_MOCK_CK_TOKEN_INFO_SERIAL_NUMBER, strlen(PKCS11_MOCK_CK_TOKEN_INFO_SERIAL_NUMBER));
+ pInfo->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED;
+ pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
+ pInfo->ulSessionCount = (CK_TRUE == pkcs11_mock_session_opened) ? 1 : 0;
+ pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
+ if ((CK_TRUE == pkcs11_mock_session_opened) && ((CKS_RO_PUBLIC_SESSION != mock_session->state) && (CKS_RO_USER_FUNCTIONS != mock_session->state)))
+ pInfo->ulRwSessionCount = 1;
+ else
+ pInfo->ulRwSessionCount = 0;
+ pInfo->ulMaxPinLen = PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN;
+ pInfo->ulMinPinLen = PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN;
+ pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
+ pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
+ pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
+ pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
+ pInfo->hardwareVersion.major = 0x01;
+ pInfo->hardwareVersion.minor = 0x00;
+ pInfo->firmwareVersion.major = 0x01;
+ pInfo->firmwareVersion.minor = 0x00;
+ memset(pInfo->utcTime, ' ', sizeof(pInfo->utcTime));
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pMechanismList)
+ {
+ *pulCount = 9;
+ }
+ else
+ {
+ if (9 > *pulCount)
+ return CKR_BUFFER_TOO_SMALL;
+
+ pMechanismList[0] = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ pMechanismList[1] = CKM_RSA_PKCS;
+ pMechanismList[2] = CKM_SHA1_RSA_PKCS;
+ pMechanismList[3] = CKM_RSA_PKCS_OAEP;
+ pMechanismList[4] = CKM_DES3_CBC;
+ pMechanismList[5] = CKM_DES3_KEY_GEN;
+ pMechanismList[6] = CKM_SHA_1;
+ pMechanismList[7] = CKM_XOR_BASE_AND_DATA;
+ pMechanismList[8] = CKM_AES_CBC;
+
+ *pulCount = 9;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (type)
+ {
+ case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_GENERATE_KEY_PAIR;
+ break;
+
+ case CKM_RSA_PKCS:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | CKF_WRAP | CKF_UNWRAP;
+ break;
+
+ case CKM_SHA1_RSA_PKCS:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_SIGN | CKF_VERIFY;
+ break;
+
+ case CKM_RSA_PKCS_OAEP:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ case CKM_DES3_CBC:
+ pInfo->ulMinKeySize = 192;
+ pInfo->ulMaxKeySize = 192;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ case CKM_DES3_KEY_GEN:
+ pInfo->ulMinKeySize = 192;
+ pInfo->ulMaxKeySize = 192;
+ pInfo->flags = CKF_GENERATE;
+ break;
+
+ case CKM_SHA_1:
+ pInfo->ulMinKeySize = 0;
+ pInfo->ulMaxKeySize = 0;
+ pInfo->flags = CKF_DIGEST;
+ break;
+
+ case CKM_XOR_BASE_AND_DATA:
+ pInfo->ulMinKeySize = 128;
+ pInfo->ulMaxKeySize = 256;
+ pInfo->flags = CKF_DERIVE;
+ break;
+
+ case CKM_AES_CBC:
+ pInfo->ulMinKeySize = 128;
+ pInfo->ulMaxKeySize = 256;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ default:
+ return CKR_MECHANISM_INVALID;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ if (NULL == pLabel)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CK_TRUE == pkcs11_mock_session_opened)
+ return CKR_SESSION_EXISTS;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (CKS_RW_SO_FUNCTIONS != mock_session->state)
+ return CKR_USER_NOT_LOGGED_IN;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((CKS_RO_PUBLIC_SESSION == mock_session->state) || (CKS_RO_USER_FUNCTIONS == mock_session->state))
+ return CKR_SESSION_READ_ONLY;
+
+ if (NULL == pOldPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulOldLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulOldLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ if (NULL == pNewPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulNewLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulNewLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (CK_TRUE == pkcs11_mock_session_opened)
+ return CKR_SESSION_COUNT;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (!(flags & CKF_SERIAL_SESSION))
+ return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
+
+ IGNORE(pApplication);
+
+ IGNORE(Notify);
+
+ if (NULL == phSession)
+ return CKR_ARGUMENTS_BAD;
+
+ pkcs11_mock_session_opened = CK_TRUE;
+
+ mock_session = calloc(1, sizeof(session_ptr_st));
+ if (mock_session == NULL)
+ return CKR_HOST_MEMORY;
+
+ mock_session->state = (flags & CKF_RW_SESSION) ? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
+
+ mock_session->find_op.find_result = CKR_OBJECT_HANDLE_INVALID;
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ mock_session->state = CKS_RO_PUBLIC_SESSION;
+
+ *phSession = PKCS11_MOCK_CK_SESSION_ID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ pkcs11_mock_session_opened = CK_FALSE;
+ mock_session->state = CKS_RO_PUBLIC_SESSION;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ free(mock_session->find_label);
+ free(mock_session);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)(CK_SLOT_ID slotID)
+{
+ return C_CloseSession(PKCS11_MOCK_CK_SESSION_ID);
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ pInfo->slotID = PKCS11_MOCK_CK_SLOT_ID;
+ pInfo->state = mock_session->state;
+ pInfo->flags = CKF_SERIAL_SESSION;
+ if ((mock_session->state != CKS_RO_PUBLIC_SESSION) && (mock_session->state != CKS_RO_USER_FUNCTIONS))
+ pInfo->flags = pInfo->flags | CKF_RW_SESSION;
+ pInfo->ulDeviceError = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulOperationStateLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pOperationState)
+ {
+ *pulOperationStateLen = 256;
+ }
+ else
+ {
+ if (256 > *pulOperationStateLen)
+ return CKR_BUFFER_TOO_SMALL;
+
+ memset(pOperationState, 1, 256);
+ *pulOperationStateLen = 256;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pOperationState)
+ return CKR_ARGUMENTS_BAD;
+
+ if (256 != ulOperationStateLen)
+ return CKR_ARGUMENTS_BAD;
+
+ IGNORE(hEncryptionKey);
+
+ IGNORE(hAuthenticationKey);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ CK_RV rv = CKR_OK;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((CKU_SO != userType) && (CKU_USER != userType))
+ return CKR_USER_TYPE_INVALID;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ switch (mock_session->state)
+ {
+ case CKS_RO_PUBLIC_SESSION:
+
+ if (CKU_SO == userType)
+ rv = CKR_SESSION_READ_ONLY_EXISTS;
+ else
+ mock_session->state = CKS_RO_USER_FUNCTIONS;
+
+ break;
+
+ case CKS_RO_USER_FUNCTIONS:
+ case CKS_RW_USER_FUNCTIONS:
+
+ rv = (CKU_SO == userType) ? CKR_USER_ANOTHER_ALREADY_LOGGED_IN : CKR_USER_ALREADY_LOGGED_IN;
+
+ break;
+
+ case CKS_RW_PUBLIC_SESSION:
+
+ mock_session->state = (CKU_SO == userType) ? CKS_RW_SO_FUNCTIONS : CKS_RW_USER_FUNCTIONS;
+
+ break;
+
+ case CKS_RW_SO_FUNCTIONS:
+
+ rv = (CKU_SO == userType) ? CKR_USER_ALREADY_LOGGED_IN : CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
+
+ break;
+ }
+
+ return rv;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((mock_session->state == CKS_RO_PUBLIC_SESSION) || (mock_session->state == CKS_RW_PUBLIC_SESSION))
+ return CKR_USER_NOT_LOGGED_IN;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phObject)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phObject = PKCS11_MOCK_CK_OBJECT_HANDLE_DATA;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == phNewObject)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((NULL != pTemplate) && (0 >= ulCount))
+ {
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+
+ *phNewObject = PKCS11_MOCK_CK_OBJECT_HANDLE_DATA;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pulSize)
+ return CKR_ARGUMENTS_BAD;
+
+ *pulSize = PKCS11_MOCK_CK_OBJECT_SIZE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE_EXTENSION != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (CKA_PUBLIC_KEY_INFO == pTemplate[i].type &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE == hObject || PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY == hObject))
+ {
+ if (pTemplate[i].ulValueLen < sizeof(mock_pubkey)-1) {
+ pTemplate[i].ulValueLen = sizeof(mock_pubkey)-1;
+ if (pTemplate[i].pValue == NULL)
+ return CKR_OK;
+ else
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = (CK_ULONG) sizeof(mock_pubkey)-1;
+ memcpy(pTemplate[i].pValue, mock_pubkey, pTemplate[i].ulValueLen);
+ }
+ else if (CKA_LABEL == pTemplate[i].type)
+ {
+ if (NULL != pTemplate[i].pValue)
+ {
+ if (pTemplate[i].ulValueLen < strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL))
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pTemplate[i].pValue, PKCS11_MOCK_CK_OBJECT_CKA_LABEL, strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL));
+ }
+
+ pTemplate[i].ulValueLen = strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL);
+ }
+ else if (CKA_ID == pTemplate[i].type)
+ {
+ if (NULL != pTemplate[i].pValue)
+ {
+ if (pTemplate[i].ulValueLen < strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL))
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pTemplate[i].pValue, PKCS11_MOCK_CK_OBJECT_CKA_LABEL, strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL));
+ }
+
+ pTemplate[i].ulValueLen = strlen(PKCS11_MOCK_CK_OBJECT_CKA_LABEL);
+ }
+ else if (CKA_CERTIFICATE_CATEGORY == pTemplate[i].type)
+ {
+ CK_ULONG t = 2; /* authority */
+ if (pTemplate[i].ulValueLen < sizeof(CK_ULONG))
+ return CKR_BUFFER_TOO_SMALL;
+ memcpy(pTemplate[i].pValue, &t, sizeof(CK_ULONG));
+ }
+ else if (CKA_VALUE == pTemplate[i].type)
+ {
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE_EXTENSION == hObject)
+ {
+ const void *obj;
+ unsigned obj_len;
+
+ if (mock_session->find_op.remaining_data == 1) {
+ obj = mock_cert_ext1;
+ obj_len = sizeof(mock_cert_ext1)-1;
+ } else {
+ obj = mock_cert_ext2;
+ obj_len = sizeof(mock_cert_ext2)-1;
+ }
+
+ if (pTemplate[i].ulValueLen < obj_len) {
+ pTemplate[i].ulValueLen = obj_len;
+ if (pTemplate[i].pValue == NULL)
+ return CKR_OK;
+ else
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = (CK_ULONG) obj_len;
+ memcpy(pTemplate[i].pValue, obj, pTemplate[i].ulValueLen);
+ }
+ else if (PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE == hObject)
+ {
+ if (pTemplate[i].ulValueLen < sizeof(mock_certificate)-1) {
+ pTemplate[i].ulValueLen = sizeof(mock_certificate)-1;
+ if (pTemplate[i].pValue == NULL)
+ return CKR_OK;
+ else
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = (CK_ULONG) sizeof(mock_certificate)-1;
+ memcpy(pTemplate[i].pValue, mock_certificate, pTemplate[i].ulValueLen);
+ }
+ else if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY == hObject)
+ {
+ if (pTemplate[i].ulValueLen < sizeof(mock_pubkey)-1) {
+ pTemplate[i].ulValueLen = sizeof(mock_pubkey)-1;
+ if (pTemplate[i].pValue == NULL)
+ return CKR_OK;
+ else
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = (CK_ULONG) sizeof(mock_pubkey)-1;
+ memcpy(pTemplate[i].pValue, mock_pubkey, pTemplate[i].ulValueLen);
+ }
+ else if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY == hObject)
+ {
+ pTemplate[i].ulValueLen = (CK_ULONG) -1;
+ }
+ else
+ {
+ if (NULL != pTemplate[i].pValue)
+ {
+ if (pTemplate[i].ulValueLen < strlen(PKCS11_MOCK_CK_OBJECT_CKA_VALUE))
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pTemplate[i].pValue, PKCS11_MOCK_CK_OBJECT_CKA_VALUE, strlen(PKCS11_MOCK_CK_OBJECT_CKA_VALUE));
+ }
+
+ pTemplate[i].ulValueLen = strlen(PKCS11_MOCK_CK_OBJECT_CKA_VALUE);
+ }
+ }
+ else
+ {
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if ((CKA_LABEL == pTemplate[i].type) || (CKA_VALUE == pTemplate[i].type))
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ else
+ {
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+ CK_ULONG_PTR cka_class_value = NULL;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ IGNORE(ulCount);
+
+ mock_session->find_op.find_result = CK_INVALID_HANDLE;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (CKA_LABEL == pTemplate[i].type)
+ {
+ if (mock_session->find_label)
+ free(mock_session->find_label);
+ mock_session->find_label = strndup(pTemplate[i].pValue, pTemplate[i].ulValueLen);
+ }
+ else if (CKA_CLASS == pTemplate[i].type)
+ {
+ if (sizeof(CK_ULONG) != pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ cka_class_value = (CK_ULONG_PTR) pTemplate[i].pValue;
+
+ switch (*cka_class_value)
+ {
+ case CKO_DATA:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_DATA;
+ mock_session->find_op.remaining_data = 2;
+ break;
+ case CKO_SECRET_KEY:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+ mock_session->find_op.remaining_data = 1;
+ break;
+ case CKO_CERTIFICATE:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE;
+ mock_session->find_op.remaining_data = 1;
+ break;
+ case CKO_PUBLIC_KEY:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY;
+ mock_session->find_op.remaining_data = 1;
+ break;
+ case CKO_PRIVATE_KEY:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY;
+ mock_session->find_op.remaining_data = 1;
+ break;
+ case CKO_X_CERTIFICATE_EXTENSION:
+ mock_session->find_op.find_result = PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE_EXTENSION;
+ mock_session->find_op.remaining_data = 2;
+ break;
+ }
+ }
+ }
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_FIND;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_FIND != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((NULL == phObject) && (0 < ulMaxObjectCount))
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulObjectCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (mock_session->find_op.remaining_data <= 0) {
+ *pulObjectCount = 0;
+ return CKR_OK;
+ }
+
+ switch (mock_session->find_op.find_result)
+ {
+ case PKCS11_MOCK_CK_OBJECT_HANDLE_DATA:
+
+ if (ulMaxObjectCount >= 2)
+ {
+ phObject[0] = mock_session->find_op.find_result;
+ phObject[1] = mock_session->find_op.find_result;
+ }
+
+ *pulObjectCount = 2;
+ mock_session->find_op.remaining_data -= 2;
+
+ break;
+
+ case CK_INVALID_HANDLE:
+
+ *pulObjectCount = 0;
+
+ break;
+
+ default:
+
+ if (ulMaxObjectCount >= 1)
+ {
+ phObject[0] = mock_session->find_op.find_result;
+ }
+
+ *pulObjectCount = 1;
+ mock_session->find_op.remaining_data --;
+
+ break;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_FIND != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN != mock_session->find_op.active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (pMechanism->mechanism)
+ {
+ case CKM_RSA_PKCS:
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+#if 0
+ case CKM_RSA_PKCS_OAEP:
+
+ if ((NULL == pMechanism->pParameter) || (sizeof(CK_RSA_PKCS_OAEP_PARAMS) != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+#endif
+ case CKM_DES3_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (8 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_AES_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (16 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ default:
+
+ return CKR_MECHANISM_INVALID;
+ }
+
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_SIGN:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_ENCRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedData)
+ {
+ if (ulDataLen > *pulEncryptedDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulDataLen; i++)
+ pEncryptedData[i] = pData[i] ^ 0xAB;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulEncryptedDataLen = ulDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_ENCRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_ENCRYPT != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != mock_session->find_op.active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulLastEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pLastEncryptedPart)
+ {
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_ENCRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_SIGN;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+
+ *pulLastEncryptedPartLen = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_VERIFY != mock_session->find_op.active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (pMechanism->mechanism)
+ {
+ case CKM_RSA_PKCS:
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+#if 0
+ case CKM_RSA_PKCS_OAEP:
+
+ if ((NULL == pMechanism->pParameter) || (sizeof(CK_RSA_PKCS_OAEP_PARAMS) != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+#endif
+ case CKM_DES3_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (8 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_AES_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (16 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ default:
+
+ return CKR_MECHANISM_INVALID;
+ }
+
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_VERIFY:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pData)
+ {
+ if (ulEncryptedDataLen > *pulDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedDataLen; i++)
+ pData[i] = pEncryptedData[i] ^ 0xAB;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDataLen = ulEncryptedDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_DECRYPT != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != mock_session->find_op.active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulLastPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pLastPart)
+ {
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+
+ *pulLastPartLen = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_ENCRYPT != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT != mock_session->find_op.active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_SHA_1 != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_ENCRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+{
+ CK_BYTE hash[20] = { 0x7B, 0x50, 0x2C, 0x3A, 0x1F, 0x48, 0xC8, 0x60, 0x9A, 0xE2, 0x12, 0xCD, 0xFB, 0x63, 0x9D, 0xEE, 0x39, 0x67, 0x3F, 0x5E };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDigestLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pDigest)
+ {
+ if (sizeof(hash) > *pulDigestLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pDigest, hash, sizeof(hash));
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDigestLen = sizeof(hash);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+{
+ CK_BYTE hash[20] = { 0x7B, 0x50, 0x2C, 0x3A, 0x1F, 0x48, 0xC8, 0x60, 0x9A, 0xE2, 0x12, 0xCD, 0xFB, 0x63, 0x9D, 0xEE, 0x39, 0x67, 0x3F, 0x5E };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_DIGEST != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != mock_session->find_op.active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulDigestLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pDigest)
+ {
+ if (sizeof(hash) > *pulDigestLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pDigest, hash, sizeof(hash));
+
+ switch (mock_session->find_op.active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST:
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+ }
+
+ *pulDigestLen = sizeof(hash);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_ENCRYPT != mock_session->find_op.active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((CKM_RSA_PKCS == pMechanism->mechanism) || (CKM_SHA1_RSA_PKCS == pMechanism->mechanism))
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE == mock_session->find_op.active_operation)
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_SIGN;
+ else
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pSignature)
+ {
+ if (sizeof(signature) > *pulSignatureLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pSignature, signature, sizeof(signature));
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulSignatureLen = sizeof(signature);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_SIGN != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != mock_session->find_op.active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pSignature)
+ {
+ if (sizeof(signature) > *pulSignatureLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pSignature, signature, sizeof(signature));
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN == mock_session->find_op.active_operation)
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ else
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ }
+ }
+
+ *pulSignatureLen = sizeof(signature);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS == pMechanism->mechanism)
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pSignature)
+ {
+ if (ulDataLen > *pulSignatureLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulDataLen; i++)
+ pSignature[i] = pData[i] ^ 0xAB;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulSignatureLen = ulDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT != mock_session->find_op.active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((CKM_RSA_PKCS == pMechanism->mechanism) || (CKM_SHA1_RSA_PKCS == pMechanism->mechanism))
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE == mock_session->find_op.active_operation)
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY;
+ else
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (sizeof(signature) != ulSignatureLen)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ if (0 != memcmp(pSignature, signature, sizeof(signature)))
+ return CKR_SIGNATURE_INVALID;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_VERIFY != mock_session->find_op.active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != mock_session->find_op.active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (sizeof(signature) != ulSignatureLen)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ if (0 != memcmp(pSignature, signature, sizeof(signature)))
+ return CKR_SIGNATURE_INVALID;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY == mock_session->find_op.active_operation)
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ else
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != mock_session->find_op.active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS == pMechanism->mechanism)
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pData)
+ {
+ if (ulSignatureLen > *pulDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulSignatureLen; i++)
+ pData[i] = pSignature[i] ^ 0xAB;
+
+ mock_session->find_op.active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDataLen = ulSignatureLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != mock_session->find_op.active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_DES3_KEY_GEN != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phKey = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS_KEY_PAIR_GEN != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (NULL == pPublicKeyTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPublicKeyAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pPrivateKeyTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPrivateKeyAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phPublicKey)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phPrivateKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulPublicKeyAttributeCount; i++)
+ {
+ if (NULL == pPublicKeyTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pPublicKeyTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ for (i = 0; i < ulPrivateKeyAttributeCount; i++)
+ {
+ if (NULL == pPrivateKeyTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pPrivateKeyTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phPublicKey = PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY;
+ *phPrivateKey = PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_WrapKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
+{
+ CK_BYTE wrappedKey[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hWrappingKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (NULL != pWrappedKey)
+ {
+ if (sizeof(wrappedKey) > *pulWrappedKeyLen)
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pWrappedKey, wrappedKey, sizeof(wrappedKey));
+ }
+
+ *pulWrappedKeyLen = sizeof(wrappedKey);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_UnwrapKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hUnwrappingKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (NULL == pWrappedKey)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulWrappedKeyLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulAttributeCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phKey = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DeriveKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
+{
+ return CKR_GENERAL_ERROR;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSeed)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSeedLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == RandomData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulRandomLen)
+ return CKR_ARGUMENTS_BAD;
+
+ memset(RandomData, 1, ulRandomLen);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionStatus)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CancelFunction)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((0 != flags) && (CKF_DONT_BLOCK != flags))
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSlot)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pReserved)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_NO_EVENT;
+}
+
diff --git a/tests/pkcs11/pkcs11-mock.h b/tests/pkcs11/pkcs11-mock.h
new file mode 100644
index 0000000000..876526497f
--- /dev/null
+++ b/tests/pkcs11/pkcs11-mock.h
@@ -0,0 +1,92 @@
+/*
+ * PKCS11-MOCK - PKCS#11 mock module
+ * Copyright (c) 2015 JWC s.r.o. <http://www.jwc.sk>
+ * Author: Jaroslav Imrich <jimrich@jimrich.sk>
+ *
+ * Licensing for open source projects:
+ * PKCS11-MOCK is available under the terms of the GNU Affero General
+ * Public License version 3 as published by the Free Software Foundation.
+ * Please see <http://www.gnu.org/licenses/agpl-3.0.html> for more details.
+ *
+ * Licensing for other types of projects:
+ * PKCS11-MOCK is available under the terms of flexible commercial license.
+ * Please contact JWC s.r.o. at <info@pkcs11interop.net> for more details.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+// PKCS#11 related stuff
+#define CK_PTR *
+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
+
+#include <p11-kit/pkcs11.h>
+#include <p11-kit/pkcs11x.h>
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#define IGNORE(P) (void)(P)
+
+#define PKCS11_MOCK_CK_INFO_MANUFACTURER_ID "Pkcs11Interop Project"
+#define PKCS11_MOCK_CK_INFO_LIBRARY_DESCRIPTION "Mock module"
+
+#define PKCS11_MOCK_CK_SLOT_ID 1
+#define PKCS11_MOCK_CK_SLOT_INFO_SLOT_DESCRIPTION "Mock slot"
+#define PKCS11_MOCK_CK_SLOT_INFO_MANUFACTURER_ID "Pkcs11Interop Project"
+
+#define PKCS11_MOCK_CK_TOKEN_INFO_LABEL "Pkcs11Interop"
+#define PKCS11_MOCK_CK_TOKEN_INFO_MANUFACTURER_ID "Pkcs11Interop Project"
+#define PKCS11_MOCK_CK_TOKEN_INFO_MODEL "Mock token"
+#define PKCS11_MOCK_CK_TOKEN_INFO_SERIAL_NUMBER "0123456789A"
+#define PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN 256
+#define PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN 4
+
+#define PKCS11_MOCK_CK_SESSION_ID 1
+
+#define PKCS11_MOCK_CK_OBJECT_CKA_LABEL "Pkcs11Interop"
+#define PKCS11_MOCK_CK_OBJECT_CKA_VALUE "Hello world!"
+#define PKCS11_MOCK_CK_OBJECT_SIZE 256
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_DATA 1
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY 2
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY 3
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY 4
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE_EXTENSION 5
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_CERTIFICATE 6
+
+typedef enum
+{
+ PKCS11_MOCK_CK_OPERATION_NONE,
+ PKCS11_MOCK_CK_OPERATION_FIND,
+ PKCS11_MOCK_CK_OPERATION_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT,
+ PKCS11_MOCK_CK_OPERATION_DIGEST,
+ PKCS11_MOCK_CK_OPERATION_SIGN,
+ PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER,
+ PKCS11_MOCK_CK_OPERATION_VERIFY,
+ PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER,
+ PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST,
+ PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY
+}
+PKCS11_MOCK_CK_OPERATION;
+
+struct find_ptr_st {
+ int remaining_data;
+ PKCS11_MOCK_CK_OPERATION active_operation;
+ CK_OBJECT_HANDLE find_result;
+};
+
+typedef struct session_ptr_st {
+ char *find_label;
+ CK_ULONG state;
+
+ struct find_ptr_st find_op;
+} session_ptr_st;
+