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