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