1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 /*
13 * Portions copyright (c) 2008 Nominet UK. All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /* find [-m module] [-s $slot] [-p pin] [-n count] */
37
38 /*! \file */
39
40 #include <inttypes.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45 #include <unistd.h>
46
47 #include <isc/commandline.h>
48 #include <isc/print.h>
49 #include <isc/result.h>
50 #include <isc/types.h>
51 #include <isc/util.h>
52
53 #include <pk11/pk11.h>
54 #include <pk11/result.h>
55
56 #ifndef HAVE_CLOCK_GETTIME
57
58 #include <sys/time.h>
59
60 #ifndef CLOCK_REALTIME
61 #define CLOCK_REALTIME 0
62 #endif /* ifndef CLOCK_REALTIME */
63
64 static int
65 clock_gettime(int32_t id, struct timespec *tp);
66
67 static int
clock_gettime(int32_t id,struct timespec * tp)68 clock_gettime(int32_t id, struct timespec *tp) {
69 struct timeval tv;
70 int result;
71
72 UNUSED(id);
73
74 result = gettimeofday(&tv, NULL);
75 if (result == 0) {
76 tp->tv_sec = tv.tv_sec;
77 tp->tv_nsec = (long)tv.tv_usec * 1000;
78 }
79 return (result);
80 }
81 #endif /* ifndef HAVE_CLOCK_GETTIME */
82
83 CK_BYTE label[] = "foo??bar!!";
84
85 int
main(int argc,char * argv[])86 main(int argc, char *argv[]) {
87 isc_result_t result;
88 CK_RV rv;
89 CK_SLOT_ID slot = 0;
90 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
91 CK_ATTRIBUTE sTemplate[] = {
92 { CKA_LABEL, label, (CK_ULONG)sizeof(label) },
93 };
94 CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE;
95 CK_ULONG found = 0;
96 pk11_context_t pctx;
97 pk11_optype_t op_type = OP_RSA;
98 char *lib_name = NULL;
99 char *pin = NULL;
100 int error = 0;
101 int c, errflg = 0;
102 unsigned int count = 1000;
103 unsigned int i;
104 struct timespec starttime;
105 struct timespec endtime;
106
107 while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) {
108 switch (c) {
109 case 'm':
110 lib_name = isc_commandline_argument;
111 break;
112 case 's':
113 slot = atoi(isc_commandline_argument);
114 op_type = OP_ANY;
115 break;
116 case 'p':
117 pin = isc_commandline_argument;
118 break;
119 case 'n':
120 count = atoi(isc_commandline_argument);
121 break;
122 case ':':
123 fprintf(stderr, "Option -%c requires an operand\n",
124 isc_commandline_option);
125 errflg++;
126 break;
127 case '?':
128 default:
129 fprintf(stderr, "Unrecognised option: -%c\n",
130 isc_commandline_option);
131 errflg++;
132 }
133 }
134
135 if (errflg) {
136 fprintf(stderr, "Usage:\n");
137 fprintf(stderr, "\tfind [-m module] [-s slot] [-p pin] [-n "
138 "count]\n");
139 exit(1);
140 }
141
142 pk11_result_register();
143
144 /* Initialize the CRYPTOKI library */
145 if (lib_name != NULL) {
146 pk11_set_lib_name(lib_name);
147 }
148
149 if (pin == NULL) {
150 pin = getpass("Enter Pin: ");
151 }
152
153 result = pk11_get_session(&pctx, op_type, false, false, true,
154 (const char *)pin, slot);
155 if ((result != ISC_R_SUCCESS) && (result != PK11_R_NORANDOMSERVICE) &&
156 (result != PK11_R_NODIGESTSERVICE) &&
157 (result != PK11_R_NOAESSERVICE))
158 {
159 fprintf(stderr, "Error initializing PKCS#11: %s\n",
160 isc_result_totext(result));
161 exit(1);
162 }
163
164 if (pin != NULL) {
165 memset(pin, 0, strlen((char *)pin));
166 }
167
168 hSession = pctx.session;
169
170 if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
171 perror("clock_gettime(start)");
172 goto exit_objects;
173 }
174
175 for (i = 0; !error && (i < count); i++) {
176 rv = pkcs_C_FindObjectsInit(hSession, sTemplate, 1);
177 if (rv != CKR_OK) {
178 fprintf(stderr,
179 "C_FindObjectsInit[%u]: Error = 0x%.8lX\n", i,
180 rv);
181 error = 1;
182 break;
183 }
184
185 rv = pkcs_C_FindObjects(hSession, &sKey, 1, &found);
186 if (rv != CKR_OK) {
187 fprintf(stderr, "C_FindObjects[%u]: Error = 0x%.8lX\n",
188 i, rv);
189 error = 1;
190 /* no break here! */
191 }
192
193 rv = pkcs_C_FindObjectsFinal(hSession);
194 if (rv != CKR_OK) {
195 fprintf(stderr,
196 "C_FindObjectsFinal[%u]: Error = 0x%.8lX\n", i,
197 rv);
198 error = 1;
199 break;
200 }
201 }
202
203 if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
204 perror("clock_gettime(end)");
205 goto exit_objects;
206 }
207
208 endtime.tv_sec -= starttime.tv_sec;
209 endtime.tv_nsec -= starttime.tv_nsec;
210 while (endtime.tv_nsec < 0) {
211 endtime.tv_sec -= 1;
212 endtime.tv_nsec += 1000000000;
213 }
214 printf("%u object searches in %ld.%09lds\n", i, endtime.tv_sec,
215 endtime.tv_nsec);
216 if (i > 0) {
217 printf("%g object searches/s\n",
218 1024 * i /
219 ((double)endtime.tv_sec +
220 (double)endtime.tv_nsec / 1000000000.));
221 }
222
223 exit_objects:
224 pk11_return_session(&pctx);
225 (void)pk11_finalize();
226
227 exit(error);
228 }
229