1 /*
2  * pkcs11-tool.c: Tool for poking around pkcs11 modules/tokens
3  *
4  * Copyright (C) 2002  Olaf Kirch <okir@suse.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include "config.h"
22 
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #ifndef _WIN32
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 #ifdef HAVE_PTHREAD
33 #include <pthread.h>
34 #endif
35 #else
36 #include <windows.h>
37 #include <io.h>
38 #endif
39 
40 #ifdef ENABLE_OPENSSL
41 #include <openssl/opensslv.h>
42 #include <openssl/opensslconf.h>
43 #include <openssl/crypto.h>
44 #include <openssl/conf.h>
45 #include <openssl/evp.h>
46 #include <openssl/x509.h>
47 #include <openssl/x509v3.h>
48 #include <openssl/asn1t.h>
49 #include <openssl/rsa.h>
50 #include <openssl/pem.h>
51 #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
52 #include <openssl/ec.h>
53 #include <openssl/ecdsa.h>
54 #endif
55 #include <openssl/bn.h>
56 #include <openssl/err.h>
57 #endif
58 
59 #include "pkcs11/pkcs11.h"
60 #include "pkcs11/pkcs11-opensc.h"
61 #include "libopensc/asn1.h"
62 #include "libopensc/log.h"
63 #include "common/compat_strlcat.h"
64 #include "common/compat_strlcpy.h"
65 #include "common/libpkcs11.h"
66 #include "util.h"
67 #include "libopensc/sc-ossl-compat.h"
68 
69 #ifdef _WIN32
70 #ifndef STDOUT_FILENO
71 #define STDOUT_FILENO 1
72 #endif
73 #endif
74 
75 #ifndef ENABLE_SHARED
76 extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0;
77 #endif
78 
79 #if defined(_WIN32) || defined(HAVE_PTHREAD)
80 #define MAX_TEST_THREADS 10
81 #endif
82 
83 #define NEED_SESSION_RO	0x01
84 #define NEED_SESSION_RW	0x02
85 
86 static struct ec_curve_info {
87 	const char *name;
88 	const char *oid;
89 	const char *ec_params;
90 	size_t size;
91 	CK_KEY_TYPE mechanism;
92 } ec_curve_infos[] = {
93 	{"secp192r1",    "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0},
94 	{"prime192v1",   "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0},
95 	{"prime192v2",   "1.2.840.10045.3.1.2", "06082A8648CE3D030102", 192, 0},
96 	{"prime192v3",   "1.2.840.10045.3.1.3", "06082A8648CE3D030103", 192, 0},
97 	{"nistp192",     "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0},
98 	{"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0},
99 
100 	{"secp224r1", "1.3.132.0.33", "06052b81040021", 224, 0},
101 	{"nistp224",  "1.3.132.0.33", "06052b81040021", 224, 0},
102 
103 	{"prime256v1",   "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0},
104 	{"secp256r1",    "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0},
105 	{"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0},
106 	{"frp256v1",	 "1.2.250.1.223.101.256.1", "060a2a817a01815f65820001", 256, 0},
107 
108 	{"secp384r1",		"1.3.132.0.34", "06052B81040022", 384, 0},
109 	{"prime384v1",		"1.3.132.0.34", "06052B81040022", 384, 0},
110 	{"ansiX9p384r1",	"1.3.132.0.34", "06052B81040022", 384, 0},
111 
112 	{"secp521r1", "1.3.132.0.35", "06052B81040023", 521, 0},
113 	{"nistp521",  "1.3.132.0.35", "06052B81040023", 521, 0},
114 
115 	{"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192, 0},
116 	{"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224, 0},
117 	{"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256, 0},
118 	{"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320, 0},
119 	{"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384, 0},
120 	{"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512, 0},
121 
122 	{"secp192k1",		"1.3.132.0.31", "06052B8104001F", 192, 0},
123 	{"secp256k1",		"1.3.132.0.10", "06052B8104000A", 256, 0},
124 
125 	{"edwards25519","1.3.6.1.4.1159.15.1", "130c656477617264733235353139", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN},
126 	{"curve25519", "1.3.6.1.4.3029.1.5.1", "130b63757276653235353139", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN},
127 
128 	{NULL, NULL, NULL, 0, 0},
129 };
130 
131 static const struct sc_aid GOST_HASH2001_PARAMSET_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }, 9 };
132 static const struct sc_aid GOST_HASH2012_256_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 }, 10 };
133 static const struct sc_aid GOST_HASH2012_512_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }, 10 };
134 
135 enum {
136 	OPT_MODULE = 0x100,
137 	OPT_SLOT,
138 	OPT_SLOT_DESCRIPTION,
139 	OPT_SLOT_INDEX,
140 	OPT_TOKEN_LABEL,
141 	OPT_APPLICATION_LABEL,
142 	OPT_APPLICATION_ID,
143 	OPT_ISSUER,
144 	OPT_SUBJECT,
145 	OPT_SO_PIN,
146 	OPT_INIT_TOKEN,
147 	OPT_INIT_PIN,
148 	OPT_ATTR_FROM,
149 	OPT_KEY_TYPE,
150 	OPT_KEY_USAGE_SIGN,
151 	OPT_KEY_USAGE_DECRYPT,
152 	OPT_KEY_USAGE_DERIVE,
153 	OPT_KEY_USAGE_WRAP,
154 	OPT_PRIVATE,
155 	OPT_SENSITIVE,
156 	OPT_EXTRACTABLE,
157 	OPT_TEST_HOTPLUG,
158 	OPT_UNLOCK_PIN,
159 	OPT_PUK,
160 	OPT_NEW_PIN,
161 	OPT_LOGIN_TYPE,
162 	OPT_TEST_EC,
163 	OPT_DERIVE,
164 	OPT_DERIVE_PASS_DER,
165 	OPT_DECRYPT,
166 	OPT_TEST_FORK,
167 #if defined(_WIN32) || defined(HAVE_PTHREAD)
168 	OPT_TEST_THREADS,
169 	OPT_USE_LOCKING,
170 #endif
171 
172 	OPT_GENERATE_KEY,
173 	OPT_GENERATE_RANDOM,
174 	OPT_HASH_ALGORITHM,
175 	OPT_MGF,
176 	OPT_SALT,
177 	OPT_VERIFY,
178 	OPT_SIGNATURE_FILE,
179 	OPT_ALWAYS_AUTH,
180 	OPT_ALLOWED_MECHANISMS,
181 	OPT_OBJECT_INDEX,
182 	OPT_ALLOW_SW,
183 	OPT_LIST_INTERFACES
184 };
185 
186 static const struct option options[] = {
187 	{ "module",		1, NULL,		OPT_MODULE },
188 	{ "show-info",		0, NULL,		'I' },
189 	{ "list-slots",		0, NULL,		'L' },
190 	{ "list-token-slots",	0, NULL,		'T' },
191 	{ "list-mechanisms",	0, NULL,		'M' },
192 	{ "list-objects",	0, NULL,		'O' },
193 	{ "list-interfaces",	0, NULL,		OPT_LIST_INTERFACES },
194 
195 	{ "sign",		0, NULL,		's' },
196 	{ "verify",		0, NULL,		OPT_VERIFY },
197 	{ "decrypt",		0, NULL,		OPT_DECRYPT },
198 	{ "hash",		0, NULL,		'h' },
199 	{ "derive",		0, NULL,		OPT_DERIVE },
200 	{ "derive-pass-der",	0, NULL,		OPT_DERIVE_PASS_DER },
201 	{ "mechanism",		1, NULL,		'm' },
202 	{ "hash-algorithm",	1, NULL,		OPT_HASH_ALGORITHM },
203 	{ "mgf",		1, NULL,		OPT_MGF },
204 	{ "salt-len",		1, NULL,		OPT_SALT },
205 
206 	{ "login",		0, NULL,		'l' },
207 	{ "login-type",		1, NULL,		OPT_LOGIN_TYPE },
208 	{ "pin",		1, NULL,		'p' },
209 	{ "puk",		1, NULL,		OPT_PUK },
210 	{ "new-pin",		1, NULL,		OPT_NEW_PIN },
211 	{ "so-pin",		1, NULL,		OPT_SO_PIN },
212 	{ "init-token",		0, NULL,		OPT_INIT_TOKEN },
213 	{ "init-pin",		0, NULL,		OPT_INIT_PIN },
214 	{ "change-pin",		0, NULL,		'c' },
215 	{ "unlock-pin",		0, NULL,		OPT_UNLOCK_PIN },
216 	{ "keypairgen",		0, NULL,		'k' },
217 	{ "keygen",		0, NULL,		OPT_GENERATE_KEY },
218 	{ "key-type",		1, NULL,		OPT_KEY_TYPE },
219 	{ "usage-sign",		0, NULL,		OPT_KEY_USAGE_SIGN },
220 	{ "usage-decrypt",	0, NULL,		OPT_KEY_USAGE_DECRYPT },
221 	{ "usage-derive",	0, NULL,		OPT_KEY_USAGE_DERIVE },
222 	{ "usage-wrap",	0, NULL,		OPT_KEY_USAGE_WRAP },
223 	{ "write-object",	1, NULL,		'w' },
224 	{ "read-object",	0, NULL,		'r' },
225 	{ "delete-object",	0, NULL,		'b' },
226 	{ "application-label",	1, NULL,		OPT_APPLICATION_LABEL },
227 	{ "application-id",	1, NULL,		OPT_APPLICATION_ID },
228 	{ "issuer",		1, NULL,		OPT_ISSUER },
229 	{ "subject",		1, NULL,		OPT_SUBJECT },
230 	{ "type",		1, NULL,		'y' },
231 	{ "id",			1, NULL,		'd' },
232 	{ "label",		1, NULL,		'a' },
233 	{ "slot",		1, NULL,		OPT_SLOT },
234 	{ "slot-description",	1, NULL,		OPT_SLOT_DESCRIPTION },
235 	{ "slot-index",		1, NULL,		OPT_SLOT_INDEX },
236 	{ "object-index",		1, NULL,		OPT_OBJECT_INDEX },
237 	{ "token-label",	1, NULL,		OPT_TOKEN_LABEL },
238 	{ "set-id",		1, NULL,		'e' },
239 	{ "attr-from",		1, NULL,		OPT_ATTR_FROM },
240 	{ "input-file",		1, NULL,		'i' },
241 	{ "signature-file",	1, NULL,		OPT_SIGNATURE_FILE },
242 	{ "output-file",	1, NULL,		'o' },
243 	{ "signature-format",	1, NULL,		'f' },
244 	{ "allowed-mechanisms",	1, NULL,		OPT_ALLOWED_MECHANISMS },
245 
246 	{ "test",		0, NULL,		't' },
247 	{ "test-hotplug",	0, NULL,		OPT_TEST_HOTPLUG },
248 	{ "moz-cert",		1, NULL,		'z' },
249 	{ "verbose",		0, NULL,		'v' },
250 	{ "private",		0, NULL,		OPT_PRIVATE },
251 	{ "sensitive",		0, NULL,		OPT_SENSITIVE },
252 	{ "extractable",	0, NULL,		OPT_EXTRACTABLE },
253 	{ "always-auth",	0, NULL,		OPT_ALWAYS_AUTH },
254 	{ "test-ec",		0, NULL,		OPT_TEST_EC },
255 #ifndef _WIN32
256 	{ "test-fork",		0, NULL,		OPT_TEST_FORK },
257 #endif
258 	{ "use-locking",	0, NULL,		OPT_USE_LOCKING },
259 #if defined(_WIN32) || defined(HAVE_PTHREAD)
260 	{ "test-threads",	1, NULL,		OPT_TEST_THREADS },
261 #endif
262 	{ "generate-random",	1, NULL,		OPT_GENERATE_RANDOM },
263 	{ "allow-sw",		0, NULL,		OPT_ALLOW_SW },
264 
265 	{ NULL, 0, NULL, 0 }
266 };
267 
268 static const char *option_help[] = {
269 	"Specify the module to load (default:" DEFAULT_PKCS11_PROVIDER ")",
270 	"Show global token information",
271 	"List available slots",
272 	"List slots with tokens",
273 	"List mechanisms supported by the token",
274 	"Show objects on token",
275 	"List interfaces of PKCS #11 3.0 library",
276 
277 	"Sign some data",
278 	"Verify a signature of some data",
279 	"Decrypt some data",
280 	"Hash some data",
281 	"Derive a secret key using another key and some data",
282 	"Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations",
283 	"Specify mechanism (use -M for a list of supported mechanisms), or by hexadecimal, e.g., 0x80001234",
284 	"Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption",
285 	"Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)",
286 	"Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)",
287 
288 	"Log into the token first",
289 	"Specify login type ('so', 'user', 'context-specific'; default:'user')",
290 	"Supply User PIN on the command line (if used in scripts: careful!)",
291 	"Supply User PUK on the command line",
292 	"Supply new User PIN on the command line",
293 	"Supply SO PIN on the command line (if used in scripts: careful!)",
294 	"Initialize the token, its label and its SO PIN (use with --label and --so-pin)",
295 	"Initialize the User PIN (use with --pin and --login)",
296 	"Change User PIN",
297 	"Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')",
298 	"Key pair generation",
299 	"Key generation",
300 	"Specify the type and length (bytes if symmetric) of the key to create, for example rsa:1024, EC:prime256v1, EC:ed25519, EC:curve25519, GOSTR3410-2012-256:B, AES:16 or GENERIC:64",
301 	"Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)",
302 	"Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)",
303 	"Specify 'derive' key usage flag (EC only)",
304 	"Specify 'wrap' key usage flag",
305 	"Write an object (key, cert, data) to the card",
306 	"Get object's CKA_VALUE attribute (use with --type)",
307 	"Delete an object (use with --type cert/data/privkey/pubkey/secrkey)",
308 	"Specify the application label of the data object (use with --type data)",
309 	"Specify the application ID of the data object (use with --type data)",
310 	"Specify the issuer in hexadecimal format (use with --type cert)",
311 	"Specify the subject in hexadecimal format (use with --type cert/privkey/pubkey)",
312 	"Specify the type of object (e.g. cert, privkey, pubkey, secrkey, data)",
313 	"Specify the ID of the object",
314 	"Specify the label of the object",
315 	"Specify the ID of the slot to use",
316 	"Specify the description of the slot to use",
317 	"Specify the index of the slot to use",
318 	"Specify the index of the object to use",
319 	"Specify the token label of the slot to use",
320 	"Set the CKA_ID of an object, <args>= the (new) CKA_ID",
321 	"Use <arg> to create some attributes when writing an object",
322 	"Specify the input file",
323 	"Specify the file with signature for verification",
324 	"Specify the output file",
325 	"Format for ECDSA signature <arg>: 'rs' (default), 'sequence', 'openssl'",
326 	"Specify the comma-separated list of allowed mechanisms when creating an object.",
327 
328 	"Test (best used with the --login or --pin option)",
329 	"Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)",
330 	"Test Mozilla-like key pair gen and cert req, <arg>=certfile",
331 	"Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)",
332 	"Set the CKA_PRIVATE attribute (object is only viewable after a login)",
333 	"Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)",
334 	"Set the CKA_EXTRACTABLE attribute (object can be extracted)",
335 	"Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)",
336 	"Test EC (best used with the --login or --pin option)",
337 #ifndef _WIN32
338 	"Test forking and calling C_Initialize() in the child",
339 #endif
340 	"Call C_initialize() with CKF_OS_LOCKING_OK.",
341 #if defined(_WIN32) || defined(HAVE_PTHREAD)
342 	"Test threads. Multiple times to start additional threads, arg is string or 2 byte commands",
343 #endif
344 	"Generate given amount of random data",
345 	"Allow using software mechanisms (without CKF_HW)",
346 };
347 
348 static const char *	app_name = "pkcs11-tool"; /* for utils.c */
349 
350 static int		verbose = 0;
351 static const char *	opt_input = NULL;
352 static const char *	opt_output = NULL;
353 static const char *	opt_signature_file = NULL;
354 static const char *	opt_module = DEFAULT_PKCS11_PROVIDER;
355 static int		opt_slot_set = 0;
356 static CK_SLOT_ID	opt_slot = 0;
357 static const char *	opt_slot_description = NULL;
358 static const char *	opt_token_label = NULL;
359 static CK_ULONG		opt_slot_index = 0;
360 static int		opt_slot_index_set = 0;
361 static CK_ULONG		opt_object_index = 0;
362 static int		opt_object_index_set = 0;
363 static CK_MECHANISM_TYPE opt_mechanism = 0;
364 static int		opt_mechanism_used = 0;
365 static const char *	opt_file_to_write = NULL;
366 static const char *	opt_object_class_str = NULL;
367 static CK_OBJECT_CLASS	opt_object_class = -1;
368 static CK_BYTE		opt_object_id[100], new_object_id[100];
369 static const char *	opt_attr_from_file = NULL;
370 static size_t		opt_object_id_len = 0, new_object_id_len = 0;
371 static char *		opt_object_label = NULL;
372 static const char *	opt_pin = NULL;
373 static const char *	opt_so_pin = NULL;
374 static const char *	opt_puk = NULL;
375 static const char *	opt_new_pin = NULL;
376 static char *		opt_application_label = NULL;
377 static char *		opt_application_id = NULL;
378 static char *		opt_issuer = NULL;
379 static char *		opt_subject = NULL;
380 static char *		opt_key_type = NULL;
381 static char *		opt_sig_format = NULL;
382 #define MAX_ALLOWED_MECHANISMS 20
383 static CK_MECHANISM_TYPE opt_allowed_mechanisms[MAX_ALLOWED_MECHANISMS];
384 static size_t		opt_allowed_mechanisms_len = 0;
385 static int		opt_is_private = 0;
386 static int		opt_is_sensitive = 0;
387 static int		opt_is_extractable = 0;
388 static int		opt_test_hotplug = 0;
389 static int		opt_login_type = -1;
390 static int		opt_key_usage_sign = 0;
391 static int		opt_key_usage_decrypt = 0;
392 static int		opt_key_usage_derive = 0;
393 static int		opt_key_usage_wrap = 0;
394 static int		opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */
395 static int		opt_derive_pass_der = 0;
396 static unsigned long	opt_random_bytes = 0;
397 static CK_MECHANISM_TYPE opt_hash_alg = 0;
398 static unsigned long	opt_mgf = 0;
399 static long	        opt_salt_len = 0;
400 static int		opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */
401 static int		opt_always_auth = 0;
402 static CK_FLAGS		opt_allow_sw = CKF_HW;
403 
404 static void *module = NULL;
405 static CK_FUNCTION_LIST_3_0_PTR p11 = NULL;
406 static CK_SLOT_ID_PTR p11_slots = NULL;
407 static CK_ULONG p11_num_slots = 0;
408 static int suppress_warn = 0;
409 static CK_C_INITIALIZE_ARGS_PTR  c_initialize_args_ptr = NULL;
410 
411 #if defined(_WIN32) || defined(HAVE_PTHREAD)
412 static CK_C_INITIALIZE_ARGS  c_initialize_args_OS = {NULL, NULL, NULL, NULL, CKF_OS_LOCKING_OK, NULL};
413 #ifdef _WIN32
414 static HANDLE test_threads_handles[MAX_TEST_THREADS];
415 #else
416 static pthread_t test_threads_handles[MAX_TEST_THREADS];
417 #endif
418 struct test_threads_data {
419 	int tnum;
420 	char * tests;
421 	volatile int state;
422 	volatile CK_RV rv;
423 };
424 static struct test_threads_data test_threads_datas[MAX_TEST_THREADS];
425 static int test_threads_num = 0;
426 #endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */
427 
428 struct flag_info {
429 	CK_FLAGS	value;
430 	const char *	name;
431 };
432 struct mech_info {
433 	CK_MECHANISM_TYPE mech;
434 	const char *	name;
435 	const char *	short_name;
436 };
437 struct x509cert_info {
438 	unsigned char	subject[512];
439 	int		subject_len;
440 	unsigned char	issuer[512];
441 	int		issuer_len;
442 	unsigned char	serialnum[128];
443 	int		serialnum_len;
444 };
445 struct rsakey_info {
446 	unsigned char	*modulus;
447 	int		modulus_len;
448 	unsigned char	*public_exponent;
449 	int		public_exponent_len;
450 	unsigned char	*private_exponent;
451 	int		private_exponent_len;
452 	unsigned char	*prime_1;
453 	int		prime_1_len;
454 	unsigned char	*prime_2;
455 	int		prime_2_len;
456 	unsigned char	*exponent_1;
457 	int		exponent_1_len;
458 	unsigned char	*exponent_2;
459 	int		exponent_2_len;
460 	unsigned char	*coefficient;
461 	int		coefficient_len;
462 };
463 struct gostkey_info {
464 	struct sc_lv_data param_oid;
465 	struct sc_lv_data public;
466 	struct sc_lv_data private;
467 };
468 
469 static void		show_cryptoki_info(void);
470 static void		list_slots(int, int, int);
471 static void		show_token(CK_SLOT_ID);
472 static void		list_mechs(CK_SLOT_ID);
473 static void		list_objects(CK_SESSION_HANDLE, CK_OBJECT_CLASS);
474 static void		list_interfaces(void);
475 static int		login(CK_SESSION_HANDLE, int);
476 static void		init_token(CK_SLOT_ID);
477 static void		init_pin(CK_SLOT_ID, CK_SESSION_HANDLE);
478 static int		change_pin(CK_SLOT_ID, CK_SESSION_HANDLE);
479 static int		unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type);
480 static void		show_object(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
481 static void		show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
482 static void		show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
483 static void		show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
484 static void		show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
485 static void		sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
486 static void		verify_signature(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
487 static void		decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
488 static void		hash_data(CK_SLOT_ID, CK_SESSION_HANDLE);
489 static void		derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
490 static int		gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE,
491 				CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *);
492 static int		gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, const char *, char *);
493 static int		write_object(CK_SESSION_HANDLE session);
494 static int		read_object(CK_SESSION_HANDLE session);
495 static int		delete_object(CK_SESSION_HANDLE session);
496 static void		set_id_attr(CK_SESSION_HANDLE session);
497 static int		find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS,
498 				CK_OBJECT_HANDLE_PTR,
499 				const unsigned char *, size_t id_len, int obj_index);
500 static int		find_mechanism(CK_SLOT_ID, CK_FLAGS, CK_MECHANISM_TYPE_PTR, size_t, CK_MECHANISM_TYPE_PTR);
501 static int		find_slot_by_description(const char *, CK_SLOT_ID_PTR);
502 static int		find_slot_by_token_label(const char *, CK_SLOT_ID_PTR);
503 static void		get_token_info(CK_SLOT_ID, CK_TOKEN_INFO_PTR);
504 static CK_ULONG		get_mechanisms(CK_SLOT_ID,
505 				CK_MECHANISM_TYPE_PTR *, CK_FLAGS);
506 static void		p11_fatal(const char *, CK_RV);
507 static void		p11_warn(const char *, CK_RV);
508 static const char *	p11_slot_info_flags(CK_FLAGS);
509 static const char *	p11_token_info_flags(CK_FLAGS);
510 static const char *	p11_utf8_to_local(CK_UTF8CHAR *, size_t);
511 static const char *	p11_flag_names(struct flag_info *, CK_FLAGS);
512 static const char *	p11_mechanism_to_name(CK_MECHANISM_TYPE);
513 static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *);
514 static const char *	p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE);
515 static CK_MECHANISM_TYPE p11_name_to_mgf(const char *);
516 static void		p11_perror(const char *, CK_RV);
517 static const char *	CKR2Str(CK_ULONG res);
518 static int		p11_test(CK_SESSION_HANDLE session);
519 static int test_card_detection(int);
520 static int		hex_to_bin(const char *in, CK_BYTE *out, size_t *outlen);
521 static void		pseudo_randomize(unsigned char *data, size_t dataLen);
522 static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
523 static void		test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
524 #ifndef _WIN32
525 static void		test_fork(void);
526 #endif
527 #if defined(_WIN32) || defined(HAVE_PTHREAD)
528 static void		test_threads();
529 static int		test_threads_start(int tnum);
530 static int		test_threads_cleanup();
531 #ifdef _WIN32
532 static DWORD WINAPI	test_threads_run(_In_ LPVOID pttd);
533 #else
534 static void *		test_threads_run(void * pttd);
535 #endif
536 #endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */
537 static void		generate_random(CK_SESSION_HANDLE session);
538 static CK_RV		find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out,
539 				CK_ATTRIBUTE *attrs, CK_ULONG attrsLen, CK_ULONG obj_index);
540 static CK_ULONG		get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey);
541 
542 /* win32 needs this in open(2) */
543 #ifndef O_BINARY
544 # define O_BINARY 0
545 #endif
546 
547 #define ATTR_METHOD(ATTR, TYPE) \
548 static TYPE \
549 get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) \
550 { \
551 	TYPE		type = 0; \
552 	CK_ATTRIBUTE	attr = { CKA_##ATTR, &type, sizeof(type) }; \
553 	CK_RV		rv; \
554  \
555 	rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \
556 	if (rv != CKR_OK) \
557 		p11_warn("C_GetAttributeValue(" #ATTR ")", rv); \
558 	return type; \
559 }
560 
561 #define VARATTR_METHOD(ATTR, TYPE) \
562 static TYPE * \
563 get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \
564 { \
565 	CK_ATTRIBUTE	attr = { CKA_##ATTR, NULL, 0 };		\
566 	CK_RV		rv;					\
567 	if (pulCount)						\
568 		*pulCount = 0;					\
569 	rv = p11->C_GetAttributeValue(sess, obj, &attr, 1);	\
570 	if (rv == CKR_OK) {					\
571 		if (attr.ulValueLen == (CK_ULONG)(-1))		\
572 			return NULL;				\
573 		if (!(attr.pValue = calloc(1, attr.ulValueLen + 1)))		\
574 			util_fatal("out of memory in get" #ATTR ": %m");	\
575 		rv = p11->C_GetAttributeValue(sess, obj, &attr, 1);		\
576 		if (attr.ulValueLen == (CK_ULONG)(-1)) {	\
577 			free(attr.pValue);			\
578 			return NULL;				\
579 		}						\
580 		if (pulCount)					\
581 			*pulCount = attr.ulValueLen / sizeof(TYPE);	\
582 	} else if (rv != CKR_ATTRIBUTE_TYPE_INVALID) {		\
583 		p11_warn("C_GetAttributeValue(" #ATTR ")", rv);	\
584 	}							\
585 	return (TYPE *) attr.pValue;				\
586 }
587 
588 /*
589  * Define attribute accessors
590  */
591 ATTR_METHOD(CLASS, CK_OBJECT_CLASS);			/* getCLASS */
592 ATTR_METHOD(ALWAYS_AUTHENTICATE, CK_BBOOL); 		/* getALWAYS_AUTHENTICATE */
593 ATTR_METHOD(PRIVATE, CK_BBOOL); 			/* getPRIVATE */
594 ATTR_METHOD(MODIFIABLE, CK_BBOOL);			/* getMODIFIABLE */
595 ATTR_METHOD(ENCRYPT, CK_BBOOL);				/* getENCRYPT */
596 ATTR_METHOD(DECRYPT, CK_BBOOL);				/* getDECRYPT */
597 ATTR_METHOD(SIGN, CK_BBOOL);				/* getSIGN */
598 ATTR_METHOD(VERIFY, CK_BBOOL);				/* getVERIFY */
599 ATTR_METHOD(WRAP, CK_BBOOL);				/* getWRAP */
600 ATTR_METHOD(UNWRAP, CK_BBOOL);				/* getUNWRAP */
601 ATTR_METHOD(DERIVE, CK_BBOOL);				/* getDERIVE */
602 ATTR_METHOD(SENSITIVE, CK_BBOOL);			/* getSENSITIVE */
603 ATTR_METHOD(ALWAYS_SENSITIVE, CK_BBOOL);		/* getALWAYS_SENSITIVE */
604 ATTR_METHOD(EXTRACTABLE, CK_BBOOL);			/* getEXTRACTABLE */
605 ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL);		/* getNEVER_EXTRACTABLE */
606 ATTR_METHOD(LOCAL, CK_BBOOL);				/* getLOCAL */
607 ATTR_METHOD(OPENSC_NON_REPUDIATION, CK_BBOOL);		/* getOPENSC_NON_REPUDIATION */
608 ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE);			/* getKEY_TYPE */
609 ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE);	/* getCERTIFICATE_TYPE */
610 ATTR_METHOD(MODULUS_BITS, CK_ULONG);			/* getMODULUS_BITS */
611 ATTR_METHOD(VALUE_LEN, CK_ULONG);			/* getVALUE_LEN */
612 ATTR_METHOD(PROFILE_ID, CK_ULONG);			/* getPROFILE_ID */
613 VARATTR_METHOD(LABEL, char);				/* getLABEL */
614 VARATTR_METHOD(APPLICATION, char);			/* getAPPLICATION */
615 VARATTR_METHOD(ID, unsigned char);			/* getID */
616 VARATTR_METHOD(OBJECT_ID, unsigned char);		/* getOBJECT_ID */
617 VARATTR_METHOD(MODULUS, CK_BYTE);			/* getMODULUS */
618 #ifdef ENABLE_OPENSSL
619 VARATTR_METHOD(SUBJECT, unsigned char);			/* getSUBJECT */
620 VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE);		/* getPUBLIC_EXPONENT */
621 #endif
622 VARATTR_METHOD(VALUE, unsigned char);			/* getVALUE */
623 VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char);	/* getGOSTR3410_PARAMS */
624 VARATTR_METHOD(GOSTR3411_PARAMS, unsigned char);	/* getGOSTR3411_PARAMS */
625 VARATTR_METHOD(EC_POINT, unsigned char);		/* getEC_POINT */
626 VARATTR_METHOD(EC_PARAMS, unsigned char);		/* getEC_PARAMS */
627 VARATTR_METHOD(ALLOWED_MECHANISMS, CK_MECHANISM_TYPE);	/* getALLOWED_MECHANISMS */
628 
main(int argc,char * argv[])629 int main(int argc, char * argv[])
630 {
631 	CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
632 	CK_OBJECT_HANDLE object = CK_INVALID_HANDLE;
633 	int err = 0, c, long_optind = 0;
634 	int do_show_info = 0;
635 	int do_list_slots = 0;
636 	int list_token_slots = 0;
637 	int do_list_mechs = 0;
638 	int do_list_objects = 0;
639 	int do_list_interfaces = 0;
640 	int do_sign = 0;
641 	int do_verify = 0;
642 	int do_decrypt = 0;
643 	int do_hash = 0;
644 	int do_derive = 0;
645 	int do_gen_keypair = 0;
646 	int do_gen_key = 0;
647 	int do_write_object = 0;
648 	int do_read_object = 0;
649 	int do_delete_object = 0;
650 	int do_set_id = 0;
651 	int do_test = 0;
652 	int do_test_kpgen_certwrite = 0;
653 	int do_test_ec = 0;
654 #ifndef _WIN32
655 	int do_test_fork = 0;
656 #endif
657 #if defined(_WIN32) || defined(HAVE_PTHREAD)
658 	int do_test_threads = 0;
659 #endif
660 	int need_session = 0;
661 	int opt_login = 0;
662 	int do_init_token = 0;
663 	int do_init_pin = 0;
664 	int do_change_pin = 0;
665 	int do_unlock_pin = 0;
666 	int action_count = 0;
667 	int do_generate_random = 0;
668 	char *s = NULL;
669 	CK_RV rv;
670 
671 #ifdef _WIN32
672 	char expanded_val[PATH_MAX];
673 	DWORD expanded_len;
674 
675 	if(_setmode(_fileno(stdout), _O_BINARY ) == -1)
676 		util_fatal("Cannot set FMODE to O_BINARY");
677 	if(_setmode(_fileno(stdin), _O_BINARY ) == -1)
678 		util_fatal("Cannot set FMODE to O_BINARY");
679 #endif
680 
681 #ifdef ENABLE_OPENSSL
682 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
683 	OPENSSL_config(NULL);
684 	/* OpenSSL magic */
685 	OpenSSL_add_all_algorithms();
686 	OPENSSL_malloc_init();
687 #endif
688 #endif
689 	while (1) {
690 		c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r",
691 		                options, &long_optind);
692 		if (c == -1)
693 			break;
694 		switch (c) {
695 		case 'I':
696 			do_show_info = 1;
697 			action_count++;
698 			break;
699 		case 'L':
700 			do_list_slots = 1;
701 			action_count++;
702 			break;
703 		case 'T':
704 			do_list_slots = 1;
705 			list_token_slots = 1;
706 			action_count++;
707 			break;
708 		case 'M':
709 			do_list_mechs = 1;
710 			action_count++;
711 			break;
712 		case 'O':
713 			need_session |= NEED_SESSION_RO;
714 			do_list_objects = 1;
715 			action_count++;
716 			break;
717 		case 'h':
718 			need_session |= NEED_SESSION_RO;
719 			do_hash = 1;
720 			action_count++;
721 			break;
722 		case 'k':
723 			need_session |= NEED_SESSION_RW;
724 			do_gen_keypair = 1;
725 			action_count++;
726 			break;
727 		case OPT_GENERATE_KEY:
728 			need_session |= NEED_SESSION_RW;
729 			do_gen_key = 1;
730 			action_count++;
731 			break;
732 		case 'w':
733 			need_session |= NEED_SESSION_RW;
734 			do_write_object = 1;
735 			opt_file_to_write = optarg;
736 			action_count++;
737 			break;
738 		case 'r':
739 			need_session |= NEED_SESSION_RO;
740 			do_read_object = 1;
741 			action_count++;
742 			break;
743 		case 'b':
744 			need_session |= NEED_SESSION_RW;
745 			do_delete_object = 1;
746 			action_count++;
747 			break;
748 		case 'e':
749 			need_session |= NEED_SESSION_RW;
750 			do_set_id = 1;
751 			new_object_id_len = sizeof(new_object_id);
752 			if (!hex_to_bin(optarg, new_object_id, &new_object_id_len)) {
753 				fprintf(stderr, "Invalid ID \"%s\"\n", optarg);
754 				util_print_usage_and_die(app_name, options, option_help, NULL);
755 			}
756 			action_count++;
757 			break;
758 		case OPT_ATTR_FROM:
759 			opt_attr_from_file = optarg;
760 			break;
761 		case 'y':
762 			opt_object_class_str = optarg;
763 			if (strcmp(optarg, "cert") == 0)
764 				opt_object_class = CKO_CERTIFICATE;
765 			else if (strcmp(optarg, "privkey") == 0)
766 				opt_object_class = CKO_PRIVATE_KEY;
767 			else if (strcmp(optarg, "secrkey") == 0)
768 				opt_object_class = CKO_SECRET_KEY;
769 			else if (strcmp(optarg, "pubkey") == 0)
770 				opt_object_class = CKO_PUBLIC_KEY;
771 			else if (strcmp(optarg, "data") == 0)
772 				opt_object_class = CKO_DATA;
773 			else {
774 				fprintf(stderr, "Unsupported object type \"%s\"\n", optarg);
775 				util_print_usage_and_die(app_name, options, option_help, NULL);
776 			}
777 			break;
778 		case 'd':
779 			opt_object_id_len = sizeof(opt_object_id);
780 			if (!hex_to_bin(optarg, opt_object_id, &opt_object_id_len)) {
781 				fprintf(stderr, "Invalid ID \"%s\"\n", optarg);
782 				util_print_usage_and_die(app_name, options, option_help, NULL);
783 			}
784 			break;
785 		case 'a':
786 			opt_object_label = optarg;
787 			break;
788 		case 'i':
789 			opt_input = optarg;
790 			break;
791 		case OPT_SIGNATURE_FILE:
792 			opt_signature_file = optarg;
793 			break;
794 		case 'l':
795 			need_session |= NEED_SESSION_RW;
796 			opt_login = 1;
797 			break;
798 		case 'm':
799 			opt_mechanism_used = 1;
800 			opt_mechanism = p11_name_to_mechanism(optarg);
801 			break;
802 		case OPT_HASH_ALGORITHM:
803 			opt_hash_alg = p11_name_to_mechanism(optarg);
804 			break;
805 		case OPT_MGF:
806 			opt_mgf = p11_name_to_mgf(optarg);
807 			break;
808 		case OPT_SALT:
809 			opt_salt_len = (CK_ULONG) strtoul(optarg, NULL, 0);
810 			opt_salt_len_given = 1;
811 			break;
812 		case 'o':
813 			opt_output = optarg;
814 			break;
815 		case 'p':
816 			need_session |= NEED_SESSION_RW;
817 			opt_login = 1;
818 			util_get_pin(optarg, &opt_pin);
819 			break;
820 		case 'c':
821 			do_change_pin = 1;
822 			need_session |= NEED_SESSION_RW;
823 			action_count++;
824 			break;
825 		case OPT_UNLOCK_PIN:
826 			do_unlock_pin = 1;
827 			need_session |= NEED_SESSION_RW;
828 			action_count++;
829 			break;
830 		case 's':
831 			need_session |= NEED_SESSION_RW;
832 			do_sign = 1;
833 			action_count++;
834 			break;
835 		case OPT_VERIFY:
836 			need_session |= NEED_SESSION_RO;
837 			do_verify = 1;
838 			action_count++;
839 			break;
840 		case OPT_DECRYPT:
841 			need_session |= NEED_SESSION_RW;
842 			do_decrypt = 1;
843 			action_count++;
844 			break;
845 		case 'f':
846 			opt_sig_format = optarg;
847 			break;
848 		case 't':
849 			need_session |= NEED_SESSION_RW;
850 			do_test = 1;
851 			action_count++;
852 			break;
853 		case 'z':
854 			do_test_kpgen_certwrite = 1;
855 			opt_file_to_write = optarg;
856 			action_count++;
857 			break;
858 		case 'v':
859 			verbose++;
860 			break;
861 		case OPT_SLOT:
862 			opt_slot = (CK_SLOT_ID) strtoul(optarg, NULL, 0);
863 			opt_slot_set = 1;
864 			if (verbose)
865 				fprintf(stderr, "Using slot with ID 0x%lx\n", opt_slot);
866 			break;
867 		case OPT_SLOT_DESCRIPTION:
868 			if (opt_slot_set) {
869 				fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n");
870 				util_print_usage_and_die(app_name, options, option_help, NULL);
871 			}
872 			opt_slot_description = optarg;
873 			break;
874 		case OPT_SLOT_INDEX:
875 			if (opt_slot_set || opt_slot_description) {
876 				fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n");
877 				util_print_usage_and_die(app_name, options, option_help, NULL);
878 			}
879 			opt_slot_index = (CK_ULONG) strtoul(optarg, NULL, 0);
880 			opt_slot_index_set = 1;
881 			break;
882 		case OPT_OBJECT_INDEX:
883 			opt_object_index = (CK_ULONG) strtoul(optarg, NULL, 0);
884 			opt_object_index_set = 1;
885 			break;
886 		case OPT_TOKEN_LABEL:
887 			if (opt_slot_set || opt_slot_description || opt_slot_index_set) {
888 				fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n");
889 				util_print_usage_and_die(app_name, options, option_help, NULL);
890 			}
891 			opt_token_label = optarg;
892 			break;
893 		case OPT_MODULE:
894 			opt_module = optarg;
895 			break;
896 		case OPT_APPLICATION_LABEL:
897 			opt_application_label = optarg;
898 			break;
899 		case OPT_APPLICATION_ID:
900 			opt_application_id = optarg;
901 			break;
902 		case OPT_ISSUER:
903 			opt_issuer = optarg;
904 			break;
905 		case OPT_SUBJECT:
906 			opt_subject = optarg;
907 			break;
908 		case OPT_NEW_PIN:
909 			util_get_pin(optarg, &opt_new_pin);
910 			break;
911 		case OPT_PUK:
912 			util_get_pin(optarg, &opt_puk);
913 			break;
914 		case OPT_LOGIN_TYPE:
915 			if (!strcmp(optarg, "so"))
916 				opt_login_type = CKU_SO;
917 			else if (!strcmp(optarg, "user"))
918 				opt_login_type = CKU_USER;
919 			else if (!strcmp(optarg, "context-specific"))
920 				opt_login_type = CKU_CONTEXT_SPECIFIC;
921 			else {
922 				fprintf(stderr, "Unsupported login type \"%s\"\n", optarg);
923 				util_print_usage_and_die(app_name, options, option_help, NULL);
924 			}
925 			break;
926 		case OPT_SO_PIN:
927 			util_get_pin(optarg, &opt_so_pin);
928 			break;
929 		case OPT_INIT_TOKEN:
930 			do_init_token = 1;
931 			action_count++;
932 			break ;
933 		case OPT_INIT_PIN:
934 			need_session |= NEED_SESSION_RW;
935 			do_init_pin = 1;
936 			action_count++;
937 			break ;
938 		case OPT_KEY_TYPE:
939 			opt_key_type = optarg;
940 			break;
941 		case OPT_KEY_USAGE_SIGN:
942 			opt_key_usage_sign = 1;
943 			opt_key_usage_default = 0;
944 			break;
945 		case OPT_KEY_USAGE_DECRYPT:
946 			opt_key_usage_decrypt = 1;
947 			opt_key_usage_default = 0;
948 			break;
949 		case OPT_KEY_USAGE_DERIVE:
950 			opt_key_usage_derive = 1;
951 			opt_key_usage_default = 0;
952 			break;
953 		case OPT_KEY_USAGE_WRAP:
954 			opt_key_usage_wrap = 1;
955 			opt_key_usage_default = 0;
956 			break;
957 		case OPT_PRIVATE:
958 			opt_is_private = 1;
959 			break;
960 		case OPT_SENSITIVE:
961 			opt_is_sensitive = 1;
962 			break;
963 		case OPT_EXTRACTABLE:
964 			opt_is_extractable = 1;
965 			break;
966 		case OPT_TEST_HOTPLUG:
967 			opt_test_hotplug = 1;
968 			action_count++;
969 			break;
970 		case OPT_TEST_EC:
971 			do_test_ec = 1;
972 			action_count++;
973 			break;
974 		case OPT_DERIVE_PASS_DER:
975 			opt_derive_pass_der = 1;
976 			/* fall through */
977 		case OPT_DERIVE:
978 			need_session |= NEED_SESSION_RW;
979 			do_derive = 1;
980 			action_count++;
981 			break;
982 #ifndef _WIN32
983 		case OPT_TEST_FORK:
984 			do_test_fork = 1;
985 			action_count++;
986 			break;
987 #endif
988 		case OPT_USE_LOCKING:
989 			c_initialize_args_ptr = &c_initialize_args_OS;
990 			break;
991 #if defined(_WIN32) || defined(HAVE_PTHREAD)
992 		case OPT_TEST_THREADS:
993 			do_test_threads = 1;
994 			if (test_threads_num < MAX_TEST_THREADS) {
995 				test_threads_datas[test_threads_num].tnum = test_threads_num;
996 				test_threads_datas[test_threads_num].tests = optarg;
997 				test_threads_num++;
998 			} else {
999 				fprintf(stderr,"Too many --test_threads options limit is %d\n", MAX_TEST_THREADS);
1000 				util_print_usage_and_die(app_name, options, option_help, NULL);
1001 			}
1002 			action_count++;
1003 			break;
1004 #endif
1005 		case OPT_GENERATE_RANDOM:
1006 			need_session |= NEED_SESSION_RO;
1007 			opt_random_bytes = strtoul(optarg, NULL, 0);
1008 			do_generate_random = 1;
1009 			action_count++;
1010 			break;
1011 		case OPT_ALWAYS_AUTH:
1012 			opt_always_auth = 1;
1013 			break;
1014 		case OPT_ALLOW_SW:
1015 			opt_allow_sw = 0;
1016 			break;
1017 		case OPT_ALLOWED_MECHANISMS:
1018 			/* Parse the mechanism list and fail early */
1019 			s = strtok(optarg, ",");
1020 			while (s != NULL) {
1021 				if (opt_allowed_mechanisms_len > MAX_ALLOWED_MECHANISMS) {
1022 					fprintf(stderr, "Too many mechanisms provided"
1023 						" (max %d). Skipping the rest.", MAX_ALLOWED_MECHANISMS);
1024 					break;
1025 				}
1026 
1027 				opt_allowed_mechanisms[opt_allowed_mechanisms_len] =
1028 					p11_name_to_mechanism(s);
1029 				opt_allowed_mechanisms_len++;
1030 				s = strtok(NULL, ",");
1031 			}
1032 			break;
1033 		case OPT_LIST_INTERFACES:
1034 			do_list_interfaces = 1;
1035 			action_count++;
1036 			break;
1037 		default:
1038 			util_print_usage_and_die(app_name, options, option_help, NULL);
1039 		}
1040 	}
1041 	if (optind < argc) {
1042 		util_fatal("invalid option(s) given");
1043 	}
1044 
1045 	if (action_count == 0)
1046 		util_print_usage_and_die(app_name, options, option_help, NULL);
1047 
1048 #ifdef _WIN32
1049 	expanded_len = PATH_MAX;
1050 	expanded_len = ExpandEnvironmentStringsA(opt_module, expanded_val, expanded_len);
1051 	if (0 < expanded_len && expanded_len < sizeof expanded_val)
1052 		opt_module = expanded_val;
1053 #endif
1054 
1055 #ifndef ENABLE_SHARED
1056 	if (strcmp(opt_module, DEFAULT_PKCS11_PROVIDER) == 0)
1057 		p11 = &pkcs11_function_list_3_0;
1058 	else
1059 #endif
1060 	{
1061 		CK_FUNCTION_LIST_PTR p11_v2 = NULL;
1062 
1063 		module = C_LoadModule(opt_module, &p11_v2);
1064 		if (module == NULL)
1065 			util_fatal("Failed to load pkcs11 module");
1066 		p11 = (CK_FUNCTION_LIST_3_0_PTR) p11_v2;
1067 	}
1068 
1069 	/* This can be done even before initialization */
1070 	if (do_list_interfaces)
1071 		list_interfaces();
1072 
1073 #if defined(_WIN32) || defined(HAVE_PTHREAD)
1074 	if (do_test_threads)
1075 		test_threads();
1076 #endif
1077 
1078 	rv = p11->C_Initialize(c_initialize_args_ptr);
1079 
1080 #if defined(_WIN32) || defined(HAVE_PTHREAD)
1081 	if (do_test_threads || rv != CKR_OK)
1082 		fprintf(stderr,"Main C_Initialize(%s) rv:%s\n",
1083 				(c_initialize_args_ptr) ? "CKF_OS_LOCKING_OK" : "NULL",  CKR2Str(rv));
1084 #else
1085 	if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
1086 		fprintf(stderr, "\n*** Cryptoki library has already been initialized ***\n");
1087 #endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */
1088 
1089 	if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)
1090 		p11_fatal("C_Initialize", rv);
1091 
1092 #ifndef _WIN32
1093 	if (do_test_fork)
1094 		test_fork();
1095 #endif
1096 
1097 	if (do_show_info)
1098 		show_cryptoki_info();
1099 
1100 	list_slots(list_token_slots, 1, do_list_slots);
1101 
1102 	if (opt_test_hotplug) {
1103 		test_card_detection(0);
1104 		test_card_detection(1);
1105 	}
1106 
1107 	if (p11_num_slots == 0) {
1108 		fprintf(stderr, "No slots.\n");
1109 		err = 1;
1110 		goto end;
1111 	}
1112 
1113 	if (!opt_slot_set && (action_count > do_list_slots)) {
1114 		if (opt_slot_description) {
1115 			if (!find_slot_by_description(opt_slot_description, &opt_slot)) {
1116 				fprintf(stderr, "No slot named \"%s\" found\n", opt_slot_description);
1117 				err = 1;
1118 				goto end;
1119 			}
1120 			if (verbose)
1121 				fprintf(stderr, "Using slot with label \"%s\" (0x%lx)\n", opt_slot_description, opt_slot);
1122 		} else if (opt_token_label) {
1123 			if (!find_slot_by_token_label(opt_token_label, &opt_slot)) {
1124 				fprintf(stderr, "No slot with token named \"%s\" found\n", opt_token_label);
1125 				err = 1;
1126 				goto end;
1127 			}
1128 			if (verbose)
1129 				fprintf(stderr, "Using slot with label \"%s\" (0x%lx)\n", opt_slot_description, opt_slot);
1130 		} else if (opt_slot_index_set) {
1131 			if (opt_slot_index < p11_num_slots) {
1132 				opt_slot = p11_slots[opt_slot_index];
1133 				fprintf(stderr, "Using slot with index %lu (0x%lx)\n", opt_slot_index, opt_slot);
1134 			} else {
1135 				fprintf(stderr, "Slot with index %lu (counting from 0) is not available.\n", opt_slot_index);
1136 				fprintf(stderr, "You must specify a valid slot with either --slot, --slot-description, --slot-index or --token-label.\n");
1137 				err = 1;
1138 				goto end;
1139 			}
1140 		} else {
1141 			/* use first slot with token present (or default slot on error) */
1142 			unsigned int i, found = 0;
1143 			for (i = 0; i < p11_num_slots; i++) {
1144 				CK_SLOT_INFO info;
1145 				rv = p11->C_GetSlotInfo(p11_slots[i], &info);
1146 				if (rv != CKR_OK)
1147 					p11_fatal("C_GetSlotInfo", rv);
1148 				if (info.flags & CKF_TOKEN_PRESENT) {
1149 					opt_slot = p11_slots[i];
1150 					fprintf(stderr, "Using slot %u with a present token (0x%lx)\n", i, opt_slot);
1151 					found = 1;
1152 					break;
1153 				}
1154 			}
1155 			if (!found) {
1156 				fprintf(stderr, "No slot with a token was found.\n");
1157 				err = 1;
1158 				goto end;
1159 			}
1160 
1161 		}
1162 	}
1163 
1164 	if (do_list_mechs)
1165 		list_mechs(opt_slot);
1166 
1167 	if (do_sign || do_decrypt) {
1168 		CK_TOKEN_INFO	info;
1169 
1170 		get_token_info(opt_slot, &info);
1171 		if (!(info.flags & CKF_TOKEN_INITIALIZED))
1172 			util_fatal("Token not initialized");
1173 		if (info.flags & CKF_LOGIN_REQUIRED)
1174 			opt_login++;
1175 	}
1176 
1177 	if (do_init_token)
1178 		init_token(opt_slot);
1179 
1180 	if (need_session) {
1181 		int flags = CKF_SERIAL_SESSION;
1182 
1183 		if (need_session & NEED_SESSION_RW)
1184 			flags |= CKF_RW_SESSION;
1185 		rv = p11->C_OpenSession(opt_slot, flags,
1186 				NULL, NULL, &session);
1187 		if (rv != CKR_OK)
1188 			p11_fatal("C_OpenSession", rv);
1189 	}
1190 
1191 	if (opt_login) {
1192 		int r;
1193 
1194 		if (opt_login_type == -1)
1195 			opt_login_type = do_init_pin ? CKU_SO : CKU_USER;
1196 
1197 		r = login(session, opt_login_type);
1198 		if (r != 0)
1199 			return r;
1200 	}
1201 
1202 	if (do_change_pin)
1203 		/* To be sure we won't mix things up with the -l or -p options,
1204 		 * we safely stop here. */
1205 		return change_pin(opt_slot, session);
1206 
1207 	if (do_unlock_pin)   {
1208 		if (opt_login_type != -1
1209 				&& opt_login_type != CKU_CONTEXT_SPECIFIC)   {
1210 			fprintf(stderr, "Invalid login type for 'Unlock User PIN' operation\n");
1211 			util_print_usage_and_die(app_name, options, option_help, NULL);
1212 		}
1213 
1214 		return unlock_pin(opt_slot, session, opt_login_type);
1215 	}
1216 
1217 	if (do_init_pin) {
1218 		init_pin(opt_slot, session);
1219 		/* We logged in as a CKU_SO user just to initialize
1220 		* the User PIN, we now have to exit. */
1221 		goto end;
1222 	}
1223 
1224 	if (do_sign || do_derive || do_decrypt) {
1225 		if (!find_object(session, CKO_PRIVATE_KEY, &object,
1226 					opt_object_id_len ? opt_object_id : NULL,
1227 					opt_object_id_len, 0))
1228 			util_fatal("Private key not found");
1229 	}
1230 
1231 	if (do_verify) {
1232 		if (!find_object(session, CKO_PUBLIC_KEY, &object,
1233 		        opt_object_id_len ? opt_object_id : NULL,
1234 		        opt_object_id_len, 0) &&
1235 		    !find_object(session, CKO_CERTIFICATE, &object,
1236 		        opt_object_id_len ? opt_object_id : NULL,
1237 		        opt_object_id_len, 0))
1238 			util_fatal("Public key nor certificate not found");
1239 	}
1240 
1241 	/* before list objects, so we can see a derived key */
1242 	if (do_derive)
1243 		derive_key(opt_slot, session, object);
1244 
1245 	if (do_list_objects)
1246 		list_objects(session, opt_object_class);
1247 
1248 	if (do_sign)
1249 		sign_data(opt_slot, session, object);
1250 
1251 	if (do_verify)
1252 		verify_signature(opt_slot, session, object);
1253 
1254 	if (do_decrypt)
1255 		decrypt_data(opt_slot, session, object);
1256 
1257 	if (do_hash)
1258 		hash_data(opt_slot, session);
1259 
1260 	if (do_gen_keypair) {
1261 		CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
1262 		gen_keypair(opt_slot, session, &hPublicKey, &hPrivateKey, opt_key_type);
1263 	}
1264 
1265 	if (do_gen_key) {
1266 		CK_OBJECT_HANDLE hSecretKey;
1267 		gen_key(opt_slot, session, &hSecretKey, opt_key_type, NULL);
1268 	}
1269 
1270 	if (do_write_object) {
1271 		if (opt_object_class_str == NULL)
1272 			util_fatal("You should specify the object type with the -y option");
1273 		write_object(session);
1274 	}
1275 
1276 	if (do_read_object) {
1277 		if (opt_object_class_str == NULL)
1278 			util_fatal("You should specify type of the object to read");
1279 		if (opt_object_id_len == 0 && opt_object_label == NULL &&
1280 				opt_application_label == NULL && opt_application_id == NULL &&
1281 				opt_issuer == NULL && opt_subject == NULL)
1282 			 util_fatal("You should specify at least one of the "
1283 					 "object ID, object label, application label or application ID");
1284 		read_object(session);
1285 	}
1286 
1287 	if (do_delete_object) {
1288 		if (opt_object_class_str == NULL)
1289 			util_fatal("You should specify type of the object to delete");
1290 		if (opt_object_id_len == 0 && opt_object_label == NULL &&
1291 				opt_application_label == NULL && opt_application_id == NULL &&
1292 				opt_object_index_set == 0)
1293 			 util_fatal("You should specify at least one of the "
1294 					 "object ID, object label, application label, application ID or object index");
1295 		delete_object(session);
1296 	}
1297 
1298 	if (do_set_id) {
1299 		if (opt_object_class_str == NULL)
1300 			util_fatal("You should specify the object type with the -y option");
1301 		if (opt_object_id_len == 0)
1302 			util_fatal("You should specify the current ID with the -d option");
1303 		set_id_attr(session);
1304 	}
1305 
1306 	if (do_test)
1307 		p11_test(session);
1308 
1309 	if (do_test_kpgen_certwrite) {
1310 		if (!opt_login)
1311 			fprintf(stderr, "ERR: login required\n");
1312 		else
1313 			session = test_kpgen_certwrite(opt_slot, session);
1314 	}
1315 
1316 	if (do_test_ec) {
1317 		if (!opt_login)
1318 			fprintf(stderr, "ERR: login required\n");
1319 		else
1320 			test_ec(opt_slot, session);
1321 	}
1322 
1323 	if (do_generate_random) {
1324 		generate_random(session);
1325 	}
1326 
1327 end:
1328 	if (session != CK_INVALID_HANDLE) {
1329 		rv = p11->C_CloseSession(session);
1330 		if (rv != CKR_OK)
1331 			p11_fatal("C_CloseSession", rv);
1332 	}
1333 
1334 #if defined(_WIN32) || defined(HAVE_PTHREAD)
1335 	if (do_test_threads)
1336 		test_threads_cleanup();
1337 #endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */
1338 
1339 	if (p11)
1340 		p11->C_Finalize(NULL_PTR);
1341 	if (module)
1342 		C_UnloadModule(module);
1343 
1344 	return err;
1345 }
1346 
1347 
show_cryptoki_info(void)1348 static void show_cryptoki_info(void)
1349 {
1350 	CK_INFO	info;
1351 	CK_RV	rv;
1352 
1353 	rv = p11->C_GetInfo(&info);
1354 	if (rv != CKR_OK)
1355 		p11_fatal("C_GetInfo", rv);
1356 
1357 	printf("Cryptoki version %u.%u\n",
1358 			info.cryptokiVersion.major,
1359 			info.cryptokiVersion.minor);
1360 	printf("Manufacturer     %s\n",
1361 			p11_utf8_to_local(info.manufacturerID,
1362 				sizeof(info.manufacturerID)));
1363 	printf("Library          %s (ver %u.%u)\n",
1364 			p11_utf8_to_local(info.libraryDescription,
1365 				sizeof(info.libraryDescription)),
1366 			info.libraryVersion.major,
1367 			info.libraryVersion.minor);
1368 }
1369 
list_interfaces(void)1370 static void list_interfaces(void)
1371 {
1372 	CK_ULONG count = 0, i;
1373 	CK_INTERFACE_PTR interfaces = NULL;
1374 	CK_RV rv;
1375 
1376 	if (p11->version.major < 3) {
1377 		fprintf(stderr, "Interfaces are supported only in PKCS #11 3.0 and newer\n");
1378 		exit(1);
1379 	}
1380 
1381 	rv = p11->C_GetInterfaceList(NULL, &count);
1382 	if (rv != CKR_OK) {
1383 		p11_fatal("C_GetInterfaceList(size inquire)", rv);
1384 	}
1385 
1386 	interfaces = malloc(count * sizeof(CK_INTERFACE));
1387 	if (interfaces == NULL) {
1388 			perror("malloc failed");
1389 			exit(1);
1390 	}
1391 	rv = p11->C_GetInterfaceList(interfaces, &count);
1392 	if (rv != CKR_OK) {
1393 		p11_fatal("C_GetInterfaceList", rv);
1394 	}
1395 	for (i = 0; i < count; i++) {
1396 		printf("Interface '%s'\n  version: %d.%d\n  funcs=%p\n  flags=0x%lu\n",
1397 			interfaces[i].pInterfaceName,
1398 			((CK_VERSION *)interfaces[i].pFunctionList)->major,
1399 			((CK_VERSION *)interfaces[i].pFunctionList)->minor,
1400 			interfaces[i].pFunctionList,
1401 			interfaces[i].flags);
1402 	}
1403 
1404 }
list_slots(int tokens,int refresh,int print)1405 static void list_slots(int tokens, int refresh, int print)
1406 {
1407 	CK_SLOT_INFO info;
1408 	CK_ULONG n;
1409 	CK_RV rv;
1410 
1411 	/* Get the list of slots */
1412 	if (refresh) {
1413 		rv = p11->C_GetSlotList(tokens, NULL, &p11_num_slots);
1414 		if (rv != CKR_OK)
1415 			p11_fatal("C_GetSlotList(NULL)", rv);
1416 		free(p11_slots);
1417 		p11_slots = NULL;
1418 		if (p11_num_slots > 0) {
1419 			p11_slots = calloc(p11_num_slots, sizeof(CK_SLOT_ID));
1420 			if (p11_slots == NULL) {
1421 				perror("calloc failed");
1422 				exit(1);
1423 			}
1424 			rv = p11->C_GetSlotList(tokens, p11_slots, &p11_num_slots);
1425 			if (rv != CKR_OK)
1426 				p11_fatal("C_GetSlotList()", rv);
1427 		}
1428 
1429 	}
1430 
1431 	if (!print)
1432 		return;
1433 
1434 	printf("Available slots:\n");
1435 	for (n = 0; n < p11_num_slots; n++) {
1436 		printf("Slot %lu (0x%lx): ", n, p11_slots[n]);
1437 		rv = p11->C_GetSlotInfo(p11_slots[n], &info);
1438 		if (rv != CKR_OK) {
1439 			printf("(GetSlotInfo failed, %s)\n", CKR2Str(rv));
1440 			continue;
1441 		}
1442 		printf("%s\n", p11_utf8_to_local(info.slotDescription,
1443 					sizeof(info.slotDescription)));
1444 		if ((!verbose) && !(info.flags & CKF_TOKEN_PRESENT)) {
1445 			printf("  (empty)\n");
1446 			continue;
1447 		}
1448 
1449 		if (verbose) {
1450 			printf("  manufacturer:  %s\n", p11_utf8_to_local(info.manufacturerID,
1451 						sizeof(info.manufacturerID)));
1452 			printf("  hardware ver:  %u.%u\n",
1453 						info.hardwareVersion.major,
1454 						info.hardwareVersion.minor);
1455 			printf("  firmware ver:  %u.%u\n",
1456 						info.firmwareVersion.major,
1457 						info.firmwareVersion.minor);
1458 			printf("  flags:         %s\n", p11_slot_info_flags(info.flags));
1459 		}
1460 		if (info.flags & CKF_TOKEN_PRESENT)
1461 			show_token(p11_slots[n]);
1462 	}
1463 }
1464 
show_token(CK_SLOT_ID slot)1465 static void show_token(CK_SLOT_ID slot)
1466 {
1467 	CK_TOKEN_INFO	info;
1468 	CK_RV rv;
1469 
1470 	rv = p11->C_GetTokenInfo(slot, &info);
1471 	if (rv == CKR_TOKEN_NOT_RECOGNIZED) {
1472 		printf("  (token not recognized)\n");
1473 		return;
1474 	} else if (rv != CKR_OK) {
1475 		printf("C_GetTokenInfo() failed: rv = %s\n", CKR2Str(rv));
1476 		return;
1477 	}
1478 	if (!(info.flags & CKF_TOKEN_INITIALIZED) && (!verbose)) {
1479 		printf("  token state:   uninitialized\n");
1480 		return;
1481 	}
1482 
1483 	printf("  token label        : %s\n",
1484 			p11_utf8_to_local(info.label,
1485 				sizeof(info.label)));
1486 	printf("  token manufacturer : %s\n",
1487 			p11_utf8_to_local(info.manufacturerID,
1488 				sizeof(info.manufacturerID)));
1489 	printf("  token model        : %s\n",
1490 			p11_utf8_to_local(info.model,
1491 				sizeof(info.model)));
1492 	printf("  token flags        : %s\n",
1493 			p11_token_info_flags(info.flags));
1494 	printf("  hardware version   : %d.%d\n", info.hardwareVersion.major, info.hardwareVersion.minor);
1495 	printf("  firmware version   : %d.%d\n", info.firmwareVersion.major, info.firmwareVersion.minor);
1496 	printf("  serial num         : %s\n", p11_utf8_to_local(info.serialNumber,
1497 			sizeof(info.serialNumber)));
1498 	printf("  pin min/max        : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen);
1499 }
1500 
list_mechs(CK_SLOT_ID slot)1501 static void list_mechs(CK_SLOT_ID slot)
1502 {
1503 	CK_MECHANISM_TYPE	*mechs = NULL;
1504 	CK_ULONG		n, num_mechs = 0;
1505 	CK_RV			rv;
1506 
1507 	num_mechs = get_mechanisms(slot, &mechs, -1);
1508 
1509 	printf("Supported mechanisms:\n");
1510 	for (n = 0; n < num_mechs; n++) {
1511 		CK_MECHANISM_INFO info;
1512 
1513 		printf("  %s", p11_mechanism_to_name(mechs[n]));
1514 		rv = p11->C_GetMechanismInfo(slot, mechs[n], &info);
1515 		if (rv == CKR_OK) {
1516 			if (info.ulMinKeySize || info.ulMaxKeySize)   {
1517 				printf(", keySize={");
1518 				if (info.ulMinKeySize)
1519 					printf("%li", info.ulMinKeySize);
1520 				printf(",");
1521 				if (info.ulMaxKeySize)
1522 					printf("%li", info.ulMaxKeySize);
1523 				printf("}");
1524 			}
1525 			if (info.flags & CKF_HW) {
1526 				printf(", hw");
1527 				info.flags &= ~CKF_HW;
1528 			}
1529 			if (info.flags & CKF_ENCRYPT) {
1530 				printf(", encrypt");
1531 				info.flags &= ~CKF_ENCRYPT;
1532 			}
1533 			if (info.flags & CKF_DECRYPT) {
1534 				printf(", decrypt");
1535 				info.flags &= ~CKF_DECRYPT;
1536 			}
1537 			if (info.flags & CKF_DIGEST) {
1538 				printf(", digest");
1539 				info.flags &= ~CKF_DIGEST;
1540 			}
1541 			if (info.flags & CKF_SIGN) {
1542 				printf(", sign");
1543 				info.flags &= ~CKF_SIGN;
1544 			}
1545 			if (info.flags & CKF_SIGN_RECOVER) {
1546 				printf(", sign_recover");
1547 				info.flags &= ~CKF_SIGN_RECOVER;
1548 			}
1549 			if (info.flags & CKF_VERIFY) {
1550 				printf(", verify");
1551 				info.flags &= ~CKF_VERIFY;
1552 			}
1553 			if (info.flags & CKF_VERIFY_RECOVER) {
1554 				printf(", verify_recover");
1555 				info.flags &= ~CKF_VERIFY_RECOVER;
1556 			}
1557 			if (info.flags & CKF_GENERATE) {
1558 				printf(", generate");
1559 				info.flags &= ~CKF_GENERATE;
1560 			}
1561 			if (info.flags & CKF_GENERATE_KEY_PAIR) {
1562 				printf(", generate_key_pair");
1563 				info.flags &= ~CKF_GENERATE_KEY_PAIR;
1564 			}
1565 			if (info.flags & CKF_WRAP) {
1566 				printf(", wrap");
1567 				info.flags &= ~CKF_WRAP;
1568 			}
1569 			if (info.flags & CKF_UNWRAP) {
1570 				printf(", unwrap");
1571 				info.flags &= ~CKF_UNWRAP;
1572 			}
1573 			if (info.flags & CKF_DERIVE) {
1574 				printf(", derive");
1575 				info.flags &= ~CKF_DERIVE;
1576 			}
1577 			if (info.flags & CKF_EC_F_P) {
1578 				printf(", EC F_P");
1579 				info.flags &= ~CKF_EC_F_P;
1580 			}
1581 			if (info.flags & CKF_EC_F_2M) {
1582 				printf(", EC F_2M");
1583 				info.flags &= ~CKF_EC_F_2M;
1584 			}
1585 			if (info.flags & CKF_EC_ECPARAMETERS) {
1586 				printf(", EC parameters");
1587 				info.flags &= ~CKF_EC_ECPARAMETERS;
1588 			}
1589 			if (info.flags & CKF_EC_OID) {
1590 				printf(", EC OID");
1591 				info.flags &= ~CKF_EC_OID;
1592 			}
1593 			if (info.flags & CKF_EC_UNCOMPRESS) {
1594 				printf(", EC uncompressed");
1595 				info.flags &= ~CKF_EC_UNCOMPRESS;
1596 			}
1597 			if (info.flags & CKF_EC_COMPRESS) {
1598 				printf(", EC compressed");
1599 				info.flags &= ~CKF_EC_COMPRESS;
1600 			}
1601 			if (info.flags & CKF_EC_CURVENAME) {
1602 				printf(", EC curve name");
1603 				info.flags &= ~CKF_EC_CURVENAME;
1604 			}
1605 			if (info.flags)
1606 				printf(", other flags=0x%x", (unsigned int) info.flags);
1607 		}
1608 		printf("\n");
1609 	}
1610 
1611 	if (mechs)
1612 		free(mechs);
1613 }
1614 
login(CK_SESSION_HANDLE session,int login_type)1615 static int login(CK_SESSION_HANDLE session, int login_type)
1616 {
1617 	char		*pin = NULL;
1618 	size_t		len = 0;
1619 	int		pin_allocated = 0, r;
1620 	CK_TOKEN_INFO	info;
1621 	CK_RV		rv;
1622 	CK_FLAGS	pin_flags;
1623 
1624 	get_token_info(opt_slot, &info);
1625 
1626 	/* Identify which pin to enter */
1627 
1628 	if (login_type == CKU_SO)
1629 		pin = (char *) opt_so_pin;
1630 	else if (login_type == CKU_USER)
1631 		pin = (char *) opt_pin;
1632 	else if (login_type == CKU_CONTEXT_SPECIFIC)
1633 		pin = opt_pin ? (char *) opt_pin : (char *) opt_puk;
1634 
1635 	if (!pin && !(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
1636 		printf("Logging in to \"%s\".\n", p11_utf8_to_local(info.label, sizeof(info.label)));
1637 		if (login_type == CKU_SO)   {
1638 			pin_flags=info.flags & (
1639 				CKF_SO_PIN_COUNT_LOW |
1640 				CKF_SO_PIN_FINAL_TRY |
1641 				CKF_SO_PIN_LOCKED |
1642 				CKF_SO_PIN_TO_BE_CHANGED);
1643 			if(pin_flags)
1644 				printf("WARNING: %s\n",p11_token_info_flags(pin_flags));
1645 
1646 			printf("Please enter SO PIN: ");
1647 		}
1648 		else if (login_type == CKU_USER)   {
1649 			pin_flags=info.flags & (
1650 				CKF_USER_PIN_COUNT_LOW |
1651 				CKF_USER_PIN_FINAL_TRY |
1652 				CKF_USER_PIN_LOCKED |
1653 				CKF_USER_PIN_TO_BE_CHANGED);
1654 			if(pin_flags)
1655 				printf("WARNING: %s\n",p11_token_info_flags(pin_flags));
1656 
1657 			printf("Please enter User PIN: ");
1658 		}
1659 		else if (login_type == CKU_CONTEXT_SPECIFIC)   {
1660 			printf("Please enter context specific PIN: ");
1661 		}
1662 
1663 		r = util_getpass(&pin, &len, stdin);
1664 		if (r < 0)
1665 			util_fatal("util_getpass error");
1666 		pin_allocated = 1;
1667 	}
1668 
1669 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
1670 			&& (!pin || !*pin)
1671 			&& login_type != CKU_CONTEXT_SPECIFIC)
1672 		return 1;
1673 
1674 	rv = p11->C_Login(session, login_type,
1675 			(CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
1676 	if (rv != CKR_OK)
1677 		p11_fatal("C_Login", rv);
1678 	if (pin_allocated)
1679 		free(pin);
1680 
1681 	return 0;
1682 }
1683 
init_token(CK_SLOT_ID slot)1684 static void init_token(CK_SLOT_ID slot)
1685 {
1686 	unsigned char token_label[33];
1687 	char new_buf[21], *new_pin = NULL;
1688 	size_t len = 0;
1689 	int pin_allocated = 0, r;
1690 	CK_TOKEN_INFO	info;
1691 	CK_RV rv;
1692 
1693 	if (!opt_object_label)
1694 		util_fatal("The token label must be specified using --label");
1695 	snprintf((char *) token_label, sizeof (token_label), "%-32.32s",
1696 			opt_object_label);
1697 
1698 	get_token_info(slot, &info);
1699 	if (opt_so_pin != NULL) {
1700 		new_pin = (char *) opt_so_pin;
1701 	} else {
1702 		if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
1703 			printf("Please enter the new SO PIN: ");
1704 			r = util_getpass(&new_pin, &len, stdin);
1705 			if (r < 0)
1706 				util_fatal("No PIN entered");
1707 			if (!new_pin || !*new_pin || strlen(new_pin) > 20)
1708 				util_fatal("Invalid SO PIN");
1709 			strlcpy(new_buf, new_pin, sizeof new_buf);
1710 			free(new_pin); new_pin = NULL;
1711 			printf("Please enter the new SO PIN (again): ");
1712 			r = util_getpass(&new_pin, &len, stdin);
1713 			if (r < 0)
1714 				util_fatal("No PIN entered");
1715 			if (!new_pin || !*new_pin ||
1716 					strcmp(new_buf, new_pin) != 0)
1717 				util_fatal("Different new SO PINs");
1718 			pin_allocated = 1;
1719 		}
1720 	}
1721 
1722 	rv = p11->C_InitToken(slot, (CK_UTF8CHAR *) new_pin,
1723 			new_pin == NULL ? 0 : strlen(new_pin), token_label);
1724 	if (rv != CKR_OK)
1725 		p11_fatal("C_InitToken", rv);
1726 	printf("Token successfully initialized\n");
1727 
1728 	if (pin_allocated)
1729 		free(new_pin);
1730 }
1731 
init_pin(CK_SLOT_ID slot,CK_SESSION_HANDLE sess)1732 static void init_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
1733 {
1734 	char *pin;
1735 	char *new_pin1 = NULL, *new_pin2 = NULL;
1736 	size_t len1 = 0, len2 = 0;
1737 	int r;
1738 	CK_TOKEN_INFO	info;
1739 	CK_RV rv;
1740 
1741 	get_token_info(slot, &info);
1742 
1743 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
1744 		if (! opt_pin && !opt_new_pin) {
1745 			printf("Please enter the new PIN: ");
1746 			r = util_getpass(&new_pin1,&len1,stdin);
1747 			if (r < 0)
1748 				util_fatal("No PIN entered");
1749 			if (!new_pin1 || !*new_pin1 || strlen(new_pin1) > 20)
1750 				util_fatal("Invalid User PIN");
1751 			printf("Please enter the new PIN again: ");
1752 			r = util_getpass(&new_pin2, &len2, stdin);
1753 			if (r < 0)
1754 				util_fatal("No PIN entered");
1755 			if (!new_pin2 || !*new_pin2 ||
1756 					strcmp(new_pin1, new_pin2) != 0)
1757 				util_fatal("Different new User PINs");
1758 		}
1759 	}
1760 
1761 	pin = (char *) opt_pin;
1762 	if (!pin) pin = (char *) opt_new_pin;
1763 	if (!pin) pin = new_pin1;
1764 
1765 	rv = p11->C_InitPIN(sess, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
1766 
1767 	if (new_pin1) {
1768 		memset(new_pin1, 0, len1);
1769 		free(new_pin1);
1770 	}
1771 	if (new_pin2) {
1772 		memset(new_pin2,0, len2);
1773 		free(new_pin2);
1774 	}
1775 
1776 	if (rv != CKR_OK)
1777 		p11_fatal("C_InitPIN", rv);
1778 	printf("User PIN successfully initialized\n");
1779 }
1780 
change_pin(CK_SLOT_ID slot,CK_SESSION_HANDLE sess)1781 static int change_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
1782 {
1783 	char old_buf[21], *old_pin = opt_so_pin ? (char*)opt_so_pin : (char*)opt_pin;
1784 	char new_buf[21], *new_pin = (char *)opt_new_pin;
1785 	CK_TOKEN_INFO	info;
1786 	CK_RV rv;
1787 	int r;
1788 	size_t		len = 0;
1789 
1790 	get_token_info(slot, &info);
1791 	const CK_FLAGS hasReaderPinPad = info.flags & CKF_PROTECTED_AUTHENTICATION_PATH;
1792 
1793 	if (!hasReaderPinPad && !old_pin) {
1794 		printf("Please enter the current PIN: ");
1795 		r = util_getpass(&old_pin, &len, stdin);
1796 		if (r < 0)
1797 			return 1;
1798 		if (!old_pin || !*old_pin || strlen(old_pin) > 20)
1799 			return 1;
1800 		strcpy(old_buf, old_pin);
1801 		old_pin = old_buf;
1802 	}
1803 	if (!hasReaderPinPad && !new_pin) {
1804 		printf("Please enter the new PIN: ");
1805 		r = util_getpass(&new_pin, &len, stdin);
1806 		if (r < 0)
1807 			return 1;
1808 		if (!new_pin || !*new_pin || strlen(new_pin) > 20)
1809 			return 1;
1810 		strcpy(new_buf, new_pin);
1811 
1812 		printf("Please enter the new PIN again: ");
1813 		r = util_getpass(&new_pin, &len, stdin);
1814 		if (r < 0)
1815 			return 1;
1816 		if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
1817 			free(new_pin);
1818 			return 1;
1819 		}
1820 	}
1821 
1822 	rv = p11->C_SetPIN(sess,
1823 		(CK_UTF8CHAR *) old_pin, old_pin == NULL ? 0 : strlen(old_pin),
1824 		(CK_UTF8CHAR *) new_pin, new_pin == NULL ? 0 : strlen(new_pin));
1825 	if (rv != CKR_OK)
1826 		p11_fatal("C_SetPIN", rv);
1827 	printf("PIN successfully changed\n");
1828 
1829 	return 0;
1830 }
1831 
1832 
unlock_pin(CK_SLOT_ID slot,CK_SESSION_HANDLE sess,int login_type)1833 static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type)
1834 {
1835 	char unlock_buf[21], *unlock_code = NULL;
1836 	char new_buf[21], *new_pin = NULL;
1837 	CK_TOKEN_INFO info;
1838 	CK_RV rv;
1839 	int r;
1840 	size_t len = 0;
1841 
1842 	get_token_info(slot, &info);
1843 
1844 	if (login_type == CKU_CONTEXT_SPECIFIC)
1845 		unlock_code = opt_pin ? (char *) opt_pin : (char *) opt_puk;
1846 	else if (login_type == -1)
1847 		unlock_code = (char *) opt_puk;
1848 	else
1849 		return 1;
1850 
1851 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) && !unlock_code)   {
1852 		if (login_type == CKU_CONTEXT_SPECIFIC)
1853 			printf("Please enter the 'Change PIN' context secret code: ");
1854 		else if (login_type == -1)
1855 			printf("Please enter unblock code for User PIN: ");
1856 
1857 		r = util_getpass(&unlock_code, &len, stdin);
1858 		if (r < 0)
1859 			return 1;
1860 		if (!unlock_code || !*unlock_code || strlen(unlock_code) > 20)
1861 			return 1;
1862 
1863 		strcpy(unlock_buf, unlock_code);
1864 		unlock_code = unlock_buf;
1865 	}
1866 
1867 	new_pin = (char *) opt_new_pin;
1868 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) && !new_pin)   {
1869 		printf("Please enter the new PIN: ");
1870 		r = util_getpass(&new_pin, &len, stdin);
1871 		if (r < 0)
1872 			return 1;
1873 		strlcpy(new_buf, new_pin, sizeof new_buf);
1874 
1875 		printf("Please enter the new PIN again: ");
1876 		r = util_getpass(&new_pin, &len, stdin);
1877 		if (r < 0)
1878 			return 1;
1879 		if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
1880 			if (new_pin != opt_new_pin)
1881 				free(new_pin);
1882 			printf("  different new PINs, exiting\n");
1883 			return -1;
1884 		}
1885 
1886 		if (!new_pin || !*new_pin || strlen(new_pin) > 20) {
1887 			if (new_pin != opt_new_pin)
1888 				free(new_pin);
1889 			return 1;
1890 		}
1891 	}
1892 
1893 	rv = p11->C_SetPIN(sess,
1894 		(CK_UTF8CHAR *) unlock_code, unlock_code == NULL ? 0 : strlen(unlock_code),
1895 		(CK_UTF8CHAR *) new_pin, new_pin == NULL ? 0 : strlen(new_pin));
1896 	if (rv != CKR_OK)
1897 		p11_fatal("C_SetPIN", rv);
1898 	printf("PIN successfully changed\n");
1899 
1900 	return 0;
1901 }
1902 
1903 /* return digest length in bytes */
hash_length(const int hash)1904 static unsigned long hash_length(const int hash) {
1905 	unsigned long sLen = 0;
1906 	switch (hash) {
1907 	case  CKM_SHA_1:
1908 		sLen = 20;
1909 		break;
1910 	case  CKM_SHA224:
1911 		sLen = 28;
1912 		break;
1913 	case  CKM_SHA256:
1914 		sLen = 32;
1915 		break;
1916 	case  CKM_SHA384:
1917 		sLen = 48;
1918 		break;
1919 	case  CKM_SHA512:
1920 		sLen = 64;
1921 		break;
1922 	default:
1923 		util_fatal("Unknown hash algorithm '%s' for RSA-PSS signatures",
1924 			p11_mechanism_to_name(hash));
1925 		break;
1926 	}
1927 	return sLen;
1928 }
1929 
1930 static unsigned long
parse_pss_params(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key,CK_MECHANISM * mech,CK_RSA_PKCS_PSS_PARAMS * pss_params)1931 parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key,
1932     CK_MECHANISM *mech, CK_RSA_PKCS_PSS_PARAMS *pss_params)
1933 {
1934 	unsigned long hashlen = 0;
1935 
1936 	if (pss_params == NULL)
1937 		return 0;
1938 
1939 	pss_params->hashAlg = 0;
1940 
1941 	if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS)
1942 		util_fatal("The hash-algorithm is applicable only to "
1943 			"RSA-PKCS-PSS mechanism");
1944 
1945 	/* set "default" MGF and hash algorithms. We can overwrite MGF later */
1946 	switch (opt_mechanism) {
1947 	case CKM_RSA_PKCS_PSS:
1948 		pss_params->hashAlg = opt_hash_alg;
1949 
1950 		switch (opt_hash_alg) {
1951 		case CKM_SHA224:
1952 			pss_params->mgf = CKG_MGF1_SHA224;
1953 			break;
1954 		case CKM_SHA256:
1955 			pss_params->mgf = CKG_MGF1_SHA256;
1956 			break;
1957 		case CKM_SHA384:
1958 			pss_params->mgf = CKG_MGF1_SHA384;
1959 			break;
1960 		case CKM_SHA512:
1961 			pss_params->mgf = CKG_MGF1_SHA512;
1962 			break;
1963 		default:
1964 			/* the PSS should use SHA-1 if not specified */
1965 			pss_params->hashAlg = CKM_SHA_1;
1966 			/* fallthrough */
1967 		case CKM_SHA_1:
1968 			pss_params->mgf = CKG_MGF1_SHA1;
1969 		}
1970 		break;
1971 
1972 	case CKM_SHA1_RSA_PKCS_PSS:
1973 		pss_params->hashAlg = CKM_SHA_1;
1974 		pss_params->mgf = CKG_MGF1_SHA1;
1975 		break;
1976 
1977 	case CKM_SHA224_RSA_PKCS_PSS:
1978 		pss_params->hashAlg = CKM_SHA224;
1979 		pss_params->mgf = CKG_MGF1_SHA224;
1980 		break;
1981 
1982 	case CKM_SHA256_RSA_PKCS_PSS:
1983 		pss_params->hashAlg = CKM_SHA256;
1984 		pss_params->mgf = CKG_MGF1_SHA256;
1985 		break;
1986 
1987 	case CKM_SHA384_RSA_PKCS_PSS:
1988 		pss_params->hashAlg = CKM_SHA384;
1989 		pss_params->mgf = CKG_MGF1_SHA384;
1990 		break;
1991 
1992 	case CKM_SHA512_RSA_PKCS_PSS:
1993 		pss_params->hashAlg = CKM_SHA512;
1994 		pss_params->mgf = CKG_MGF1_SHA512;
1995 		break;
1996 
1997 	default: /* The non-RSA-PSS algorithms do not need any parameters */
1998 		return 0;
1999 	}
2000 
2001 	/* One of RSA-PSS mechanisms above: They need parameters */
2002 	if (pss_params->hashAlg) {
2003 		if (opt_mgf != 0)
2004 			pss_params->mgf = opt_mgf;
2005 
2006 		hashlen = hash_length(pss_params->hashAlg);
2007 
2008 		if (opt_salt_len_given == 1) { /* salt size explicitly given */
2009 			unsigned long modlen = 0;
2010 			if (opt_salt_len < 0 && opt_salt_len != -1 && opt_salt_len != -2)
2011 				util_fatal("Salt length must be greater or equal "
2012 				    "to zero, or equal to -1 (meaning: use digest size) "
2013 				    "or to -2 (meaning: use maximum permissible size");
2014 
2015 			modlen = (get_private_key_length(session, key) + 7) / 8;
2016 			switch (opt_salt_len) {
2017 			case -1: /* salt size equals to digest size */
2018 				pss_params->sLen = hashlen;
2019 				break;
2020 			case -2: /* maximum permissible salt len */
2021 				pss_params->sLen = modlen - hashlen -2;
2022 				break;
2023 			default: /* use given size but its value must be >= 0 */
2024 				pss_params->sLen = opt_salt_len;
2025 				break;
2026 			} /* end switch (opt_salt_len_given) */
2027 		} else { /* use default: salt len of digest size */
2028 			pss_params->sLen = hashlen;
2029 		}
2030 
2031 		mech->pParameter = pss_params;
2032 		mech->ulParameterLen = sizeof(*pss_params);
2033 
2034 		fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt_len=%lu B\n",
2035 			p11_mechanism_to_name(pss_params->hashAlg),
2036 			p11_mgf_to_name(pss_params->mgf),
2037 			pss_params->sLen);
2038 	}
2039 	return hashlen;
2040 }
2041 
sign_data(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key)2042 static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
2043 		CK_OBJECT_HANDLE key)
2044 {
2045 	unsigned char	in_buffer[1025], sig_buffer[512];
2046 	CK_MECHANISM	mech;
2047 	CK_RSA_PKCS_PSS_PARAMS pss_params;
2048 	CK_RV		rv;
2049 	CK_ULONG	sig_len;
2050 	int		fd, r;
2051 	unsigned long	hashlen;
2052 
2053 	if (!opt_mechanism_used)
2054 		if (!find_mechanism(slot, CKF_SIGN|opt_allow_sw, NULL, 0, &opt_mechanism))
2055 			util_fatal("Sign mechanism not supported");
2056 
2057 	fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
2058 	memset(&mech, 0, sizeof(mech));
2059 	mech.mechanism = opt_mechanism;
2060 	hashlen = parse_pss_params(session, key, &mech, &pss_params);
2061 
2062 	if (opt_input == NULL)
2063 		fd = 0;
2064 	else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0)
2065 		util_fatal("Cannot open %s: %m", opt_input);
2066 
2067 	r = read(fd, in_buffer, sizeof(in_buffer));
2068 	if (r < 0)
2069 		util_fatal("Cannot read from %s: %m", opt_input);
2070 
2071 	if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) {
2072 		util_fatal("For %s mechanism, message size (got %d bytes) "
2073 			"must be equal to specified digest length (%lu)\n",
2074 			p11_mechanism_to_name(opt_mechanism), r, hashlen);
2075 	}
2076 
2077 	rv = CKR_CANCEL;
2078 	if (r < (int) sizeof(in_buffer)) {
2079 		rv = p11->C_SignInit(session, &mech, key);
2080 		if (rv != CKR_OK)
2081 			p11_fatal("C_SignInit", rv);
2082 		if (getALWAYS_AUTHENTICATE(session, key))
2083 			login(session,CKU_CONTEXT_SPECIFIC);
2084 
2085 		sig_len = sizeof(sig_buffer);
2086 		rv =  p11->C_Sign(session, in_buffer, r, sig_buffer, &sig_len);
2087 	}
2088 
2089 	if (rv != CKR_OK)   {
2090 		rv = p11->C_SignInit(session, &mech, key);
2091 		if (rv != CKR_OK)
2092 			p11_fatal("C_SignInit", rv);
2093 		if (getALWAYS_AUTHENTICATE(session, key))
2094 			login(session,CKU_CONTEXT_SPECIFIC);
2095 
2096 		do   {
2097 			rv = p11->C_SignUpdate(session, in_buffer, r);
2098 			if (rv != CKR_OK)
2099 				p11_fatal("C_SignUpdate", rv);
2100 
2101 			r = read(fd, in_buffer, sizeof(in_buffer));
2102 		} while (r > 0);
2103 
2104 		sig_len = sizeof(sig_buffer);
2105 		rv = p11->C_SignFinal(session, sig_buffer, &sig_len);
2106 		if (rv != CKR_OK)
2107 			p11_fatal("C_SignFinal", rv);
2108 	}
2109 
2110 	if (fd != 0)
2111 		close(fd);
2112 
2113 	if (opt_output == NULL)
2114 		fd = 1;
2115 	else if ((fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
2116 		util_fatal("failed to open %s: %m", opt_output);
2117 	}
2118 
2119 	if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 ||
2120 	    opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 ||
2121 	    opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) {
2122 		if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") ||
2123 		                       !strcmp(opt_sig_format, "sequence"))) {
2124 			unsigned char *seq;
2125 			size_t seqlen;
2126 
2127 			if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer,
2128 			    sig_len, &seq, &seqlen)) {
2129 				util_fatal("Failed to convert signature to ASN.1 sequence format");
2130 			}
2131 
2132 			memcpy(sig_buffer, seq, seqlen);
2133 			sig_len = seqlen;
2134 
2135 			free(seq);
2136 		}
2137 	}
2138 	r = write(fd, sig_buffer, sig_len);
2139 
2140 	if (r < 0)
2141 		util_fatal("Failed to write to %s: %m", opt_output);
2142 	if (fd != 1)
2143 		close(fd);
2144 }
2145 
verify_signature(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key)2146 static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
2147 		CK_OBJECT_HANDLE key)
2148 {
2149 	unsigned char	in_buffer[1025], sig_buffer[512];
2150 	CK_MECHANISM	mech;
2151 	CK_RSA_PKCS_PSS_PARAMS pss_params;
2152 	CK_RV		rv;
2153 	CK_ULONG	sig_len;
2154 	int		fd, fd2, r, r2;
2155 	unsigned long   hashlen;
2156 
2157 	if (!opt_mechanism_used)
2158 		if (!find_mechanism(slot, CKF_VERIFY|opt_allow_sw, NULL, 0, &opt_mechanism))
2159 			util_fatal("Mechanism not supported for signature verification");
2160 
2161 	fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
2162 	memset(&mech, 0, sizeof(mech));
2163 	mech.mechanism = opt_mechanism;
2164 	hashlen = parse_pss_params(session, key, &mech, &pss_params);
2165 
2166 	/* Open a signature file */
2167 	if (opt_signature_file == NULL)
2168 		util_fatal("No file with signature provided. Use --signature-file");
2169 	else if ((fd2 = open(opt_signature_file, O_RDONLY|O_BINARY)) < 0)
2170 		util_fatal("Cannot open %s: %m", opt_signature_file);
2171 
2172 	r2 = read(fd2, sig_buffer, sizeof(sig_buffer));
2173 	if (r2 < 0)
2174 		util_fatal("Cannot read from %s: %m", opt_signature_file);
2175 
2176 	close(fd2);
2177 
2178 	if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 ||
2179 		opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 ||
2180 		opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) {
2181 		if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") ||
2182 							   !strcmp(opt_sig_format, "sequence"))) {
2183 
2184 			CK_BYTE* bytes;
2185 			CK_ULONG len;
2186 			size_t rs_len = 0;
2187 			unsigned char rs_buffer[512];
2188 			bytes = getEC_POINT(session, key, &len);
2189 			free(bytes);
2190 			/*
2191 			 * (We only support uncompressed for now)
2192 			 * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y"
2193 			 * So a "256" bit key has x and y of 32 bytes each
2194 			 * something like: "04 41 04||x||y"
2195 			 * Do simple size calculation based on DER encoding
2196 			 */
2197 			if ((len - 2) <= 127)
2198 				rs_len = len - 3;
2199 			else if ((len - 3) <= 255)
2200 				rs_len = len - 4;
2201 			else
2202 				util_fatal("Key not supported");
2203 
2204 			if (sc_asn1_sig_value_sequence_to_rs(NULL, sig_buffer, r2,
2205 				rs_buffer, rs_len)) {
2206 				util_fatal("Failed to convert ASN.1 signature");
2207 			}
2208 
2209 			memcpy(sig_buffer, rs_buffer, rs_len);
2210 			r2 = rs_len;
2211 		}
2212 	}
2213 
2214 	/* Open the data file */
2215 	if (opt_input == NULL)
2216 		fd = 0;
2217 	else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0)
2218 		util_fatal("Cannot open %s: %m", opt_input);
2219 
2220 	r = read(fd, in_buffer, sizeof(in_buffer));
2221 	if (r < 0)
2222 		util_fatal("Cannot read from %s: %m", opt_input);
2223 
2224 	if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) {
2225 		util_fatal("For %s mechanism, message size (got %d bytes)"
2226 			" must be equal to specified digest length (%lu)\n",
2227 			p11_mechanism_to_name(opt_mechanism), r, hashlen);
2228 	}
2229 
2230 	rv = CKR_CANCEL;
2231 	if (r < (int) sizeof(in_buffer)) {
2232 		rv = p11->C_VerifyInit(session, &mech, key);
2233 		if (rv != CKR_OK)
2234 			p11_fatal("C_VerifyInit", rv);
2235 
2236 		sig_len = r2;
2237 		rv =  p11->C_Verify(session, in_buffer, r, sig_buffer, sig_len);
2238 	}
2239 
2240 	if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID) {
2241 		rv = p11->C_VerifyInit(session, &mech, key);
2242 		if (rv != CKR_OK)
2243 			p11_fatal("C_VerifyInit", rv);
2244 
2245 		do   {
2246 			rv = p11->C_VerifyUpdate(session, in_buffer, r);
2247 			if (rv != CKR_OK)
2248 				p11_fatal("C_VerifyUpdate", rv);
2249 
2250 			r = read(fd, in_buffer, sizeof(in_buffer));
2251 		} while (r > 0);
2252 
2253 		sig_len = r2;
2254 		rv = p11->C_VerifyFinal(session, sig_buffer, sig_len);
2255 		if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID)
2256 			p11_fatal("C_VerifyFinal", rv);
2257 	}
2258 
2259 	if (fd != 0)
2260 		close(fd);
2261 
2262 	if (rv == CKR_OK)
2263 		printf("Signature is valid\n");
2264 	else if (rv == CKR_SIGNATURE_INVALID)
2265 		printf("Invalid signature\n");
2266 	else
2267 		printf("Cryptoki returned error: %s\n", CKR2Str(rv));
2268 }
2269 
2270 
decrypt_data(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key)2271 static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
2272 		CK_OBJECT_HANDLE key)
2273 {
2274 	unsigned char	in_buffer[1024], out_buffer[1024];
2275 	CK_MECHANISM	mech;
2276 	CK_RV		rv;
2277 	CK_RSA_PKCS_OAEP_PARAMS oaep_params;
2278 	CK_ULONG	in_len, out_len;
2279 	int		fd, r;
2280 
2281 	if (!opt_mechanism_used)
2282 		if (!find_mechanism(slot, CKF_DECRYPT|opt_allow_sw, NULL, 0, &opt_mechanism))
2283 			util_fatal("Decrypt mechanism not supported");
2284 
2285 	fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
2286 	memset(&mech, 0, sizeof(mech));
2287 	mech.mechanism = opt_mechanism;
2288 	oaep_params.hashAlg = 0;
2289 
2290 	if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP)
2291 		util_fatal("The hash-algorithm is applicable only to "
2292                "RSA-PKCS-OAEP mechanism");
2293 
2294 	if (opt_input == NULL)
2295 		fd = 0;
2296 	else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0)
2297 		util_fatal("Cannot open %s: %m", opt_input);
2298 
2299 	r = read(fd, in_buffer, sizeof(in_buffer));
2300 	if (r < 0)
2301 		util_fatal("Cannot read from %s: %m", opt_input);
2302 	in_len = r;
2303 
2304 	/* set "default" MGF and hash algorithms. We can overwrite MGF later */
2305 	switch (opt_mechanism) {
2306 	case CKM_RSA_PKCS_OAEP:
2307 		oaep_params.hashAlg = opt_hash_alg;
2308 		switch (opt_hash_alg) {
2309 		case CKM_SHA_1:
2310 			oaep_params.mgf = CKG_MGF1_SHA1;
2311 			break;
2312 		case CKM_SHA224:
2313 			oaep_params.mgf = CKG_MGF1_SHA224;
2314 			break;
2315 		default:
2316 			oaep_params.hashAlg = CKM_SHA256;
2317 			/* fall through */
2318 		case CKM_SHA256:
2319 			oaep_params.mgf = CKG_MGF1_SHA256;
2320 			break;
2321 		case CKM_SHA384:
2322 			oaep_params.mgf = CKG_MGF1_SHA384;
2323 			break;
2324 		case CKM_SHA512:
2325 			oaep_params.mgf = CKG_MGF1_SHA512;
2326 			break;
2327 		}
2328 		break;
2329 	case CKM_RSA_X_509:
2330 	case CKM_RSA_PKCS:
2331 		mech.pParameter = NULL;
2332 		mech.ulParameterLen = 0;
2333 		break;
2334 	default:
2335 		util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism));
2336 	}
2337 
2338 
2339 	/* If an RSA-OAEP mechanism, it needs parameters */
2340 	if (oaep_params.hashAlg) {
2341 		if (opt_mgf != 0)
2342 			oaep_params.mgf = opt_mgf;
2343 
2344 		/* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */
2345 		oaep_params.source = 0UL;  /* empty encoding parameter (label) */
2346 		oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */
2347 		oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */
2348 
2349 		mech.pParameter = &oaep_params;
2350 		mech.ulParameterLen = sizeof(oaep_params);
2351 
2352 		fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n",
2353 			p11_mechanism_to_name(oaep_params.hashAlg),
2354 			p11_mgf_to_name(oaep_params.mgf),
2355 			oaep_params.source,
2356 			oaep_params.pSourceData,
2357 			oaep_params.ulSourceDataLen);
2358 
2359 	}
2360 
2361 	rv = p11->C_DecryptInit(session, &mech, key);
2362 	if (rv != CKR_OK)
2363 		p11_fatal("C_DecryptInit", rv);
2364 	if (getALWAYS_AUTHENTICATE(session, key))
2365 		login(session,CKU_CONTEXT_SPECIFIC);
2366 
2367 	out_len = sizeof(out_buffer);
2368 	rv = p11->C_Decrypt(session, in_buffer, in_len, out_buffer, &out_len);
2369 	if (rv != CKR_OK)
2370 		p11_fatal("C_Decrypt", rv);
2371 
2372 	if (fd != 0)
2373 		close(fd);
2374 
2375 	if (opt_output == NULL)   {
2376 		fd = 1;
2377 	}
2378 	else  {
2379 		fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR);
2380 		if (fd < 0)
2381 			util_fatal("failed to open %s: %m", opt_output);
2382 	}
2383 
2384 	r = write(fd, out_buffer, out_len);
2385 	if (r < 0)
2386 		util_fatal("Failed to write to %s: %m", opt_output);
2387 	if (fd != 1)
2388 		close(fd);
2389 }
2390 
2391 
hash_data(CK_SLOT_ID slot,CK_SESSION_HANDLE session)2392 static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
2393 {
2394 	unsigned char	buffer[64];
2395 	CK_MECHANISM	mech;
2396 	CK_RV		rv;
2397 	CK_ULONG	hash_len;
2398 	int		fd, r;
2399 
2400 	if (!opt_mechanism_used)
2401 		if (!find_mechanism(slot, CKF_DIGEST, NULL, 0, &opt_mechanism))
2402 			util_fatal("Digest mechanism is not supported");
2403 
2404 	fprintf(stderr, "Using digest algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
2405 	memset(&mech, 0, sizeof(mech));
2406 	mech.mechanism = opt_mechanism;
2407 
2408 	rv = p11->C_DigestInit(session, &mech);
2409 	if (rv != CKR_OK)
2410 		p11_fatal("C_DigestInit", rv);
2411 
2412 	if (opt_input == NULL)
2413 		fd = 0;
2414 	else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0)
2415 		util_fatal("Cannot open %s: %m", opt_input);
2416 
2417 	while ((r = read(fd, buffer, sizeof(buffer))) > 0) {
2418 		rv = p11->C_DigestUpdate(session, buffer, r);
2419 		if (rv != CKR_OK)
2420 			p11_fatal("C_DigestUpdate", rv);
2421 	}
2422 
2423 	if (fd != 0)
2424 		close(fd);
2425 
2426 	hash_len = sizeof(buffer);
2427 	rv = p11->C_DigestFinal(session, buffer, &hash_len);
2428 	if (rv != CKR_OK)
2429 		p11_fatal("C_DigestFinal", rv);
2430 
2431 	if (opt_output == NULL)
2432 		fd = 1;
2433 	else if ((fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR)) < 0)
2434 		util_fatal("failed to open %s: %m", opt_output);
2435 
2436 	r = write(fd, buffer, hash_len);
2437 	if (r < 0)
2438 		util_fatal("Failed to write to %s: %m", opt_output);
2439 	if (fd != 1)
2440 		close(fd);
2441 }
2442 
2443 #define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;}
2444 
2445 /* Generate asymmetric key pair */
gen_keypair(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE * hPublicKey,CK_OBJECT_HANDLE * hPrivateKey,const char * type)2446 static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
2447 	CK_OBJECT_HANDLE *hPublicKey, CK_OBJECT_HANDLE *hPrivateKey, const char *type)
2448 {
2449 	CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
2450 	CK_ULONG modulusBits = 1024;
2451 	CK_BYTE publicExponent[] = { 0x01, 0x00, 0x01 }; /* 65537 in bytes */
2452 	CK_BBOOL _true = TRUE;
2453 	CK_BBOOL _false = FALSE;
2454 	CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
2455 	CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY;
2456 	CK_ATTRIBUTE publicKeyTemplate[20] = {
2457 		{CKA_CLASS, &pubkey_class, sizeof(pubkey_class)},
2458 		{CKA_TOKEN, &_true, sizeof(_true)},
2459 	};
2460 	int n_pubkey_attr = 2;
2461 	CK_ATTRIBUTE privateKeyTemplate[20] = {
2462 		{CKA_CLASS, &privkey_class, sizeof(privkey_class)},
2463 		{CKA_TOKEN, &_true, sizeof(_true)},
2464 		{CKA_PRIVATE, &_true, sizeof(_true)},
2465 		{CKA_SENSITIVE, &_true, sizeof(_true)},
2466 	};
2467 	int n_privkey_attr = 4;
2468 	unsigned char *ecparams = NULL;
2469 	size_t ecparams_size;
2470 	CK_ULONG key_type = CKK_RSA;
2471 	CK_RV rv;
2472 
2473 	if (type != NULL) {
2474 		if (strncmp(type, "RSA:", strlen("RSA:")) == 0 || strncmp(type, "rsa:", strlen("rsa:")) == 0) {
2475 			CK_MECHANISM_TYPE mtypes[] = {CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_X9_31_KEY_PAIR_GEN};
2476 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2477 			CK_ULONG    key_length;
2478 			const char *size = type + strlen("RSA:");
2479 
2480 			if (!opt_mechanism_used)
2481 				if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism))
2482 					util_fatal("Generate RSA mechanism not supported");
2483 
2484 			if (size == NULL)
2485 				util_fatal("Unknown key type %s", type);
2486 			key_length = (unsigned long)atol(size);
2487 			if (key_length != 0)
2488 				modulusBits = key_length;
2489 
2490 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits));
2491 			n_pubkey_attr++;
2492 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent));
2493 			n_pubkey_attr++;
2494 
2495 			if (opt_key_usage_default || opt_key_usage_sign) {
2496 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true));
2497 				n_pubkey_attr++;
2498 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true));
2499 				n_privkey_attr++;
2500 			}
2501 
2502 			if (opt_key_usage_default || opt_key_usage_decrypt) {
2503 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ENCRYPT, &_true, sizeof(_true));
2504 				n_pubkey_attr++;
2505 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DECRYPT, &_true, sizeof(_true));
2506 				n_privkey_attr++;
2507 			}
2508 
2509 			if (opt_key_usage_wrap) {
2510 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_WRAP, &_true, sizeof(_true));
2511 				n_pubkey_attr++;
2512 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_UNWRAP, &_true, sizeof(_true));
2513 				n_privkey_attr++;
2514 			}
2515 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2516 			n_pubkey_attr++;
2517 			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2518 			n_privkey_attr++;
2519 		}
2520 		else if (strncmp(type, "EC:", strlen("EC:")) == 0 || strncmp(type, "ec:", strlen("ec:")) == 0)  {
2521 			CK_MECHANISM_TYPE mtypes[] = {CKM_EC_KEY_PAIR_GEN};
2522 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2523 			int ii;
2524 
2525 			key_type = CKK_EC;
2526 
2527 			for (ii=0; ec_curve_infos[ii].name; ii++)   {
2528 				if (!strcmp(ec_curve_infos[ii].name, type + 3))
2529 					break;
2530 				if (!strcmp(ec_curve_infos[ii].oid, type + 3))
2531 					break;
2532 			}
2533 			if (!ec_curve_infos[ii].name)
2534 				util_fatal("Unknown EC key params '%s'", type + 3);
2535 
2536 			switch (ec_curve_infos[ii].mechanism) {
2537 			case CKM_EC_EDWARDS_KEY_PAIR_GEN:
2538 				/* The Edwards key can not be used for derivation */
2539 				opt_key_usage_derive = 0;
2540 				key_type = CKK_EC_EDWARDS;
2541 				/* This replaces the above default mechanism */
2542 				if (!opt_mechanism_used) {
2543 					mtypes[0] = ec_curve_infos[ii].mechanism;
2544 				}
2545 				break;
2546 			case CKM_EC_MONTGOMERY_KEY_PAIR_GEN:
2547 				key_type = CKK_EC_MONTGOMERY;
2548 				/* This replaces the above default mechanism */
2549 				if (!opt_mechanism_used) {
2550 					mtypes[0] = ec_curve_infos[ii].mechanism;
2551 				}
2552 				break;
2553 			}
2554 
2555 			if (!opt_mechanism_used) {
2556 				if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num,
2557 						&opt_mechanism)) {
2558 					util_fatal("Generate EC key mechanism %lx not supported", mtypes[0]);
2559 				}
2560 			}
2561 
2562 			ecparams_size = strlen(ec_curve_infos[ii].ec_params) / 2;
2563 			ecparams = malloc(ecparams_size);
2564 			if (!ecparams)
2565 				util_fatal("Allocation error", 0);
2566 			if (!hex_to_bin(ec_curve_infos[ii].ec_params, ecparams, &ecparams_size)) {
2567 				fprintf(stderr, "Cannot convert \"%s\"\n", ec_curve_infos[ii].ec_params);
2568 				util_print_usage_and_die(app_name, options, option_help, NULL);
2569 			}
2570 
2571 			if (opt_key_usage_default || opt_key_usage_sign) {
2572 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true));
2573 				n_pubkey_attr++;
2574 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true));
2575 				n_privkey_attr++;
2576 			}
2577 
2578 			if (opt_key_usage_default || opt_key_usage_derive) {
2579 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_DERIVE, &_true, sizeof(_true));
2580 				n_pubkey_attr++;
2581 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true));
2582 				n_privkey_attr++;
2583 			}
2584 
2585 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ecparams, ecparams_size);
2586 			n_pubkey_attr++;
2587 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2588 			n_pubkey_attr++;
2589 			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2590 			n_privkey_attr++;
2591 		}
2592 		else if (strncmp(type, "GOSTR3410", strlen("GOSTR3410")) == 0 || strncmp(type, "gostr3410", strlen("gostr3410")) == 0) {
2593 			const struct sc_aid GOST2001_PARAMSET_A_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 }, 9 };
2594 			const struct sc_aid GOST2001_PARAMSET_B_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 }, 9 };
2595 			const struct sc_aid GOST2001_PARAMSET_C_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 }, 9 };
2596 			const struct sc_aid GOST2012_256_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x01, 0x01 }, 11 };
2597 			const struct sc_aid GOST2012_512_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 }, 11 };
2598 			const struct sc_aid GOST2012_512_PARAMSET_B_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x02 }, 11 };
2599 			const struct sc_aid GOST2012_512_PARAMSET_C_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x03 }, 11 };
2600 			struct sc_aid key_paramset_encoded_oid;
2601 			struct sc_aid hash_paramset_encoded_oid;
2602 			unsigned long int gost_key_type = -1;
2603 			CK_MECHANISM_TYPE mtypes[] = {-1};
2604 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2605 			const char *p_param_set = type + strlen("GOSTR3410");
2606 
2607 			if (p_param_set == NULL)
2608 				util_fatal("Unknown key type %s", type);
2609 
2610 			if (!strcmp(":A", p_param_set) || !strcmp("-2001:A", p_param_set)) {
2611 				gost_key_type = CKK_GOSTR3410;
2612 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2613 				key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID;
2614 				hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID;
2615 			}
2616 			else if (!strcmp(":B", p_param_set) || !strcmp("-2001:B", p_param_set)) {
2617 				gost_key_type = CKK_GOSTR3410;
2618 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2619 				key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID;
2620 				hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID;
2621 			}
2622 			else if (!strcmp(":C", p_param_set) || !strcmp("-2001:C", p_param_set)) {
2623 				gost_key_type = CKK_GOSTR3410;
2624 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2625 				key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID;
2626 				hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID;
2627 			} else if (!strcmp("-2012-256:A", p_param_set)) {
2628 				gost_key_type = CKK_GOSTR3410;
2629 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2630 				key_paramset_encoded_oid = GOST2012_256_PARAMSET_A_OID;
2631 				hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID;
2632 			}
2633 			else if (!strcmp("-2012-256:B", p_param_set)) {
2634 				gost_key_type = CKK_GOSTR3410;
2635 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2636 				key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID;
2637 				hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID;
2638 			}
2639 			else if (!strcmp("-2012-256:C", p_param_set)) {
2640 				gost_key_type = CKK_GOSTR3410;
2641 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2642 				key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID;
2643 				hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID;
2644 			}
2645 			else if (!strcmp("-2012-256:D", p_param_set)) {
2646 				gost_key_type = CKK_GOSTR3410;
2647 				mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN;
2648 				key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID;
2649 				hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID;
2650 			}
2651 			else if (!strcmp("-2012-512:A", p_param_set)) {
2652 				gost_key_type = CKK_GOSTR3410_512;
2653 				mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN;
2654 				key_paramset_encoded_oid = GOST2012_512_PARAMSET_A_OID;
2655 				hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID;
2656 			}
2657 			else if (!strcmp("-2012-512:B", p_param_set)) {
2658 				gost_key_type = CKK_GOSTR3410_512;
2659 				mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN;
2660 				key_paramset_encoded_oid = GOST2012_512_PARAMSET_B_OID;
2661 				hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID;
2662 			}
2663 			else if (!strcmp("-2012-512:C", p_param_set)) {
2664 				gost_key_type = CKK_GOSTR3410_512;
2665 				mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN;
2666 				key_paramset_encoded_oid = GOST2012_512_PARAMSET_C_OID;
2667 				hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID;
2668 			}
2669 			else
2670 				util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410-2001:{A,B,C},"
2671 					" GOSTR3410-2012-256:{A,B,C,D}, GOSTR3410-2012-512:{A,B,C}", type);
2672 
2673 			if (!opt_mechanism_used) {
2674 				if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism))
2675 					util_fatal("Generate GOSTR3410%s mechanism not supported", gost_key_type == CKK_GOSTR3410_512 ? "-2012-512" : "");
2676 			}
2677 
2678 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len);
2679 			n_pubkey_attr++;
2680 			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len);
2681 			n_privkey_attr++;
2682 
2683 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len);
2684 			n_pubkey_attr++;
2685 			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len);
2686 			n_privkey_attr++;
2687 
2688 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type));
2689 			n_pubkey_attr++;
2690 			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type));
2691 			n_privkey_attr++;
2692 
2693 			if (opt_key_usage_default || opt_key_usage_sign) {
2694 				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true));
2695 				n_pubkey_attr++;
2696 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true));
2697 				n_privkey_attr++;
2698 			}
2699 
2700 			/* do not set 'derive' attribute unless it is specified directly */
2701 			if (opt_key_usage_derive) {
2702 				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true));
2703 				n_privkey_attr++;
2704 			}
2705 		}
2706 		else {
2707 			util_fatal("Unknown key type %s", type);
2708 		}
2709 
2710 		mechanism.mechanism = opt_mechanism;
2711 	}
2712 
2713 	if (opt_object_label != NULL) {
2714 		FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_LABEL,
2715 			opt_object_label, strlen(opt_object_label));
2716 		FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_LABEL,
2717 			opt_object_label, strlen(opt_object_label));
2718 		n_pubkey_attr++;
2719 		n_privkey_attr++;
2720 
2721 	}
2722 	if (opt_object_id_len != 0) {
2723 		FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ID,
2724 			opt_object_id, opt_object_id_len);
2725 		FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ID,
2726 			opt_object_id, opt_object_id_len);
2727 		n_pubkey_attr++;
2728 		n_privkey_attr++;
2729 	}
2730 
2731 	if (opt_is_private != 0) {
2732 		FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PRIVATE,
2733 			&_true, sizeof(_true));
2734 		n_pubkey_attr++;
2735 	}
2736 	else {
2737 		FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PRIVATE,
2738 			&_false, sizeof(_false));
2739 		n_pubkey_attr++;
2740 	}
2741 
2742 	if (opt_always_auth != 0) {
2743 		FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE,
2744 				&_true, sizeof(_true));
2745 		n_privkey_attr++;
2746 	}
2747 
2748 	if (opt_is_extractable != 0) {
2749 		FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_EXTRACTABLE,
2750 				&_true, sizeof(_true));
2751 		n_privkey_attr++;
2752 	}
2753 
2754 	if (opt_allowed_mechanisms_len > 0) {
2755 		FILL_ATTR(privateKeyTemplate[n_privkey_attr],
2756 			CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
2757 			sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
2758 		n_privkey_attr++;
2759 	}
2760 
2761 	rv = p11->C_GenerateKeyPair(session, &mechanism,
2762 		publicKeyTemplate, n_pubkey_attr,
2763 		privateKeyTemplate, n_privkey_attr,
2764 		hPublicKey, hPrivateKey);
2765 	if (rv != CKR_OK)
2766 		p11_fatal("C_GenerateKeyPair", rv);
2767 
2768 	if (ecparams)
2769 		free(ecparams);
2770 
2771 	printf("Key pair generated:\n");
2772 	show_object(session, *hPrivateKey);
2773 	show_object(session, *hPublicKey);
2774 
2775 	return 1;
2776 }
2777 
2778 /* generate symmetric key */
2779 static int
gen_key(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE * hSecretKey,const char * type,char * label)2780 gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey,
2781 	const char *type, char *label)
2782 {
2783 	CK_MECHANISM mechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0};
2784 	CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY;
2785 	CK_BBOOL _true = TRUE;
2786 	CK_BBOOL _false = FALSE;
2787 	CK_KEY_TYPE key_type = CKK_AES;
2788 	CK_ULONG    key_length;
2789 	CK_ATTRIBUTE keyTemplate[20] = {
2790 		{CKA_CLASS, &secret_key_class, sizeof(secret_key_class)},
2791 		{CKA_TOKEN, &_true, sizeof(_true)},
2792 	};
2793 	int n_attr = 2;
2794 	CK_RV rv;
2795 
2796 	if (type != NULL) {
2797 		if (strncasecmp(type, "AES:", strlen("AES:")) == 0) {
2798 			CK_MECHANISM_TYPE mtypes[] = {CKM_AES_KEY_GEN};
2799 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2800 			const char *size = type + strlen("AES:");
2801 
2802 			key_type = CKK_AES;
2803 
2804 			if (!opt_mechanism_used)
2805 				if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism))
2806 					util_fatal("Generate Key mechanism not supported\n");
2807 
2808 			if (size == NULL)
2809 				util_fatal("Unknown key type %s", type);
2810 			key_length = (unsigned long)atol(size);
2811 			if (key_length == 0)
2812 				key_length = 32;
2813 
2814 			FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2815 			n_attr++;
2816 		}
2817 		else if (strncasecmp(type, "DES:", strlen("DES:")) == 0) {
2818 			CK_MECHANISM_TYPE mtypes[] = {CKM_DES_KEY_GEN};
2819 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2820 			const char *size = type + strlen("DES:");
2821 
2822 			key_type = CKK_DES;
2823 
2824 			if (!opt_mechanism_used)
2825 				if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism))
2826 					util_fatal("Generate Key mechanism not supported\n");
2827 
2828 			if (size == NULL)
2829 				util_fatal("Unknown key type %s", type);
2830 			key_length = (unsigned long)atol(size);
2831 			if (key_length == 0)
2832 				key_length = 8;
2833 
2834 			FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2835 			n_attr++;
2836 		}
2837 		else if (strncasecmp(type, "DES3:", strlen("DES3:")) == 0) {
2838 			CK_MECHANISM_TYPE mtypes[] = {CKM_DES3_KEY_GEN};
2839 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2840 			const char *size = type + strlen("DES3:");
2841 
2842 			key_type = CKK_DES3;
2843 
2844 			if (!opt_mechanism_used)
2845 				if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism))
2846 					util_fatal("Generate Key mechanism not supported\n");
2847 
2848 			if (size == NULL)
2849 				util_fatal("Unknown key type %s", type);
2850 			key_length = (unsigned long)atol(size);
2851 			if (key_length == 0)
2852 				key_length = 16;
2853 
2854 			FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2855 			n_attr++;
2856 		}
2857 		else if (strncasecmp(type, "GENERIC:", strlen("GENERIC:")) == 0) {
2858 			CK_MECHANISM_TYPE mtypes[] = {CKM_GENERIC_SECRET_KEY_GEN};
2859 			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
2860 			const char *size = type + strlen("GENERIC:");
2861 
2862 			key_type = CKK_GENERIC_SECRET;
2863 
2864 			if (!opt_mechanism_used)
2865 				if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism))
2866 					util_fatal("Generate Key mechanism not supported\n");
2867 
2868 			if (size == NULL)
2869 				util_fatal("Unknown key type %s", type);
2870 			key_length = (unsigned long)atol(size);
2871 			if (key_length == 0)
2872 				key_length = 32;
2873 
2874 			FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
2875 			n_attr++;
2876 		}
2877 		else {
2878 			util_fatal("Unknown key type %s", type);
2879 		}
2880 
2881 		if (opt_is_sensitive != 0) {
2882 			FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true));
2883 			n_attr++;
2884 		}
2885 		else {
2886 			FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false));
2887 			n_attr++;
2888 		}
2889 
2890 		FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true));
2891 		n_attr++;
2892 		FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true));
2893 		n_attr++;
2894 		FILL_ATTR(keyTemplate[n_attr], CKA_WRAP, &_true, sizeof(_true));
2895 		n_attr++;
2896 		FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true));
2897 		n_attr++;
2898 		FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length));
2899 		n_attr++;
2900 
2901 		mechanism.mechanism = opt_mechanism;
2902 	}
2903 
2904 	if (label != NULL) {
2905 		FILL_ATTR(keyTemplate[n_attr], CKA_LABEL, label, strlen(label));
2906 		n_attr++;
2907 	}
2908 	else if (opt_object_label != NULL) {
2909 		FILL_ATTR(keyTemplate[n_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label));
2910 		n_attr++;
2911 	}
2912 
2913 	if (opt_object_id_len != 0) {
2914 		FILL_ATTR(keyTemplate[n_attr], CKA_ID, opt_object_id, opt_object_id_len);
2915 		n_attr++;
2916 	}
2917 
2918 	if (opt_allowed_mechanisms_len > 0) {
2919 		FILL_ATTR(keyTemplate[n_attr],
2920 			CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
2921 			sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
2922 		n_attr++;
2923 	}
2924 
2925 	rv = p11->C_GenerateKey(session, &mechanism, keyTemplate, n_attr, hSecretKey);
2926 	if (rv != CKR_OK)
2927 		p11_fatal("C_GenerateKey", rv);
2928 
2929 	printf("Key generated:\n");
2930 	show_object(session, *hSecretKey);
2931 	return 1;
2932 }
2933 
2934 
2935 #ifdef ENABLE_OPENSSL
parse_certificate(struct x509cert_info * cert,unsigned char * data,int len,unsigned char * contents,int * contents_len)2936 static void	parse_certificate(struct x509cert_info *cert,
2937 		unsigned char *data, int len, unsigned char *contents,
2938 		int *contents_len)
2939 {
2940 	X509 *x = NULL;
2941 	unsigned char *p;
2942 	int n;
2943 
2944 	if (strstr((char *)data, "-----BEGIN CERTIFICATE-----")) {
2945 		BIO *mem = BIO_new_mem_buf(data, len);
2946 		x = PEM_read_bio_X509(mem, NULL, NULL, NULL);
2947 		/* Update what is written to the card to be DER encoded */
2948 		if (contents != NULL) {
2949 			unsigned char *contents_pointer = contents;
2950 			*contents_len = i2d_X509(x, &contents_pointer);
2951 			if (*contents_len < 0)
2952 				util_fatal("Failed to convert PEM to DER");
2953 		}
2954 		BIO_free(mem);
2955 	} else {
2956 		x = d2i_X509(NULL, (const unsigned char **)&data, len);
2957 	}
2958 	if (!x) {
2959 		util_fatal("OpenSSL error during X509 certificate parsing");
2960 	}
2961 	/* convert only (if needed) */
2962 	if (cert == NULL)
2963 		return;
2964 
2965 	/* check length first */
2966 	n = i2d_X509_NAME(X509_get_subject_name(x), NULL);
2967 	if (n < 0)
2968 		util_fatal("OpenSSL error while encoding subject name");
2969 	if (n > (int)sizeof (cert->subject))
2970 		util_fatal("subject name too long");
2971 	/* green light, actually do it */
2972 	p = cert->subject;
2973 	n = i2d_X509_NAME(X509_get_subject_name(x), &p);
2974 	cert->subject_len = n;
2975 
2976 	/* check length first */
2977 	n = i2d_X509_NAME(X509_get_issuer_name(x), NULL);
2978 	if (n < 0)
2979 		util_fatal("OpenSSL error while encoding issuer name");
2980 	if (n > (int)sizeof (cert->issuer))
2981 		util_fatal("issuer name too long");
2982 	/* green light, actually do it */
2983 	p = cert->issuer;
2984 	n =i2d_X509_NAME(X509_get_issuer_name(x), &p);
2985 	cert->issuer_len = n;
2986 
2987 	/* check length first */
2988 	n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL);
2989 	if (n < 0)
2990 		util_fatal("OpenSSL error while encoding serial number");
2991 	if (n > (int)sizeof (cert->serialnum))
2992 		util_fatal("serial number too long");
2993 	/* green light, actually do it */
2994 	p = cert->serialnum;
2995 	n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &p);
2996 	cert->serialnum_len = n;
2997 }
2998 
2999 static int
do_read_key(unsigned char * data,size_t data_len,int private,EVP_PKEY ** key)3000 do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key)
3001 {
3002 	BIO *mem = BIO_new_mem_buf(data, data_len);;
3003 
3004 	if (!key)
3005 		return -1;
3006 
3007 	if (private) {
3008 		if (!strstr((char *)data, "-----BEGIN "))
3009 			*key = d2i_PrivateKey_bio(mem, NULL);
3010 		else
3011 			*key = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
3012 	}
3013 	else {
3014 		if (!strstr((char *)data, "-----BEGIN "))
3015 			*key = d2i_PUBKEY_bio(mem, NULL);
3016 		else
3017 			*key = PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL);
3018 	}
3019 
3020 	BIO_free(mem);
3021 	if (*key == NULL)
3022 		return -1;
3023 
3024 	return 0;
3025 }
3026 
3027 #define RSA_GET_BN(RSA, LOCALNAME, BNVALUE) \
3028 	do { \
3029 		if (BNVALUE) { \
3030 			RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \
3031 			if (!RSA->LOCALNAME) \
3032 				util_fatal("malloc() failure\n"); \
3033 			RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \
3034 		} else { \
3035 			RSA->LOCALNAME##_len = 0; \
3036 			RSA->LOCALNAME = NULL; \
3037 		} \
3038 	} while (0)
3039 
3040 static int
parse_rsa_pkey(EVP_PKEY * pkey,int private,struct rsakey_info * rsa)3041 parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
3042 {
3043 	RSA *r;
3044 	const BIGNUM *r_n, *r_e, *r_d;
3045 	const BIGNUM *r_p, *r_q;
3046 	const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp;
3047 
3048 	r = EVP_PKEY_get1_RSA(pkey);
3049 	if (!r) {
3050 		if (private)
3051 			util_fatal("OpenSSL error during RSA private key parsing");
3052 		else
3053 			util_fatal("OpenSSL error during RSA public key parsing");
3054 	}
3055 
3056 	RSA_get0_key(r, &r_n, &r_e, NULL);
3057 	RSA_GET_BN(rsa, modulus, r_n);
3058 	RSA_GET_BN(rsa, public_exponent, r_e);
3059 
3060 	if (private) {
3061 		RSA_get0_key(r, NULL, NULL, &r_d);
3062 		RSA_GET_BN(rsa, private_exponent, r_d);
3063 
3064 		RSA_get0_factors(r, &r_p, &r_q);
3065 		RSA_GET_BN(rsa, prime_1, r_p);
3066 		RSA_GET_BN(rsa, prime_2, r_q);
3067 
3068 		RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp);
3069 		RSA_GET_BN(rsa, exponent_1, r_dmp1);
3070 		RSA_GET_BN(rsa, exponent_2, r_dmq1);
3071 		RSA_GET_BN(rsa, coefficient, r_iqmp);
3072 	}
3073 
3074 	RSA_free(r);
3075 
3076 	return 0;
3077 }
3078 
3079 #if !defined(OPENSSL_NO_EC)
3080 static int
parse_gost_pkey(EVP_PKEY * pkey,int private,struct gostkey_info * gost)3081 parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost)
3082 {
3083 	EC_KEY *src = EVP_PKEY_get0(pkey);
3084 	unsigned char *pder;
3085 	const BIGNUM *bignum;
3086 	BIGNUM *X, *Y;
3087 	const EC_POINT *point;
3088 	int nid, rv;
3089 
3090 	if (!src)
3091 		return -1;
3092 
3093 	nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0(pkey)));
3094 	rv = i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL);
3095 	if (rv < 0)
3096 		return -1;
3097 
3098 	gost->param_oid.value = malloc(rv);
3099 	if (!gost->param_oid.value)
3100 		return -1;
3101 
3102 	pder =  gost->param_oid.value;
3103 	rv = i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &pder);
3104 	gost->param_oid.len = rv;
3105 
3106 	if (private) {
3107 		bignum = EC_KEY_get0_private_key(EVP_PKEY_get0(pkey));
3108 
3109 		gost->private.len = BN_num_bytes(bignum);
3110 		gost->private.value = malloc(gost->private.len);
3111 		if (!gost->private.value)
3112 			return -1;
3113 		BN_bn2bin(bignum, gost->private.value);
3114 	}
3115 	else {
3116 		X = BN_new();
3117 		Y = BN_new();
3118 		point = EC_KEY_get0_public_key(src);
3119 		rv = -1;
3120 		if (X && Y && point && EC_KEY_get0_group(src))
3121 			rv = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(src),
3122 					point, X, Y, NULL);
3123 		if (rv == 1) {
3124 			gost->public.len = BN_num_bytes(X) + BN_num_bytes(Y);
3125 			gost->public.value = malloc(gost->public.len);
3126 			if (!gost->public.value)
3127 				rv = -1;
3128 			else
3129 			{
3130 				BN_bn2bin(Y, gost->public.value);
3131 				BN_bn2bin(X, gost->public.value + BN_num_bytes(Y));
3132 			}
3133 		}
3134 		BN_free(X);
3135 		BN_free(Y);
3136 		if (rv != 1)
3137 			return -1;
3138 	}
3139 
3140 	return 0;
3141 }
3142 
3143 static int
parse_ec_pkey(EVP_PKEY * pkey,int private,struct gostkey_info * gost)3144 parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost)
3145 {
3146 	const EC_KEY *src = EVP_PKEY_get0_EC_KEY(pkey);
3147 	const BIGNUM *bignum;
3148 
3149 	if (!src)
3150 		return -1;
3151 
3152 	gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gost->param_oid.value);
3153 	if (gost->param_oid.len <= 0)
3154 		return -1;
3155 
3156 	if (private) {
3157 		bignum = EC_KEY_get0_private_key(src);
3158 
3159 		gost->private.len = BN_num_bytes(bignum);
3160 		gost->private.value = malloc(gost->private.len);
3161 		if (!gost->private.value)
3162 			return -1;
3163 		BN_bn2bin(bignum, gost->private.value);
3164 	}
3165 	else {
3166 		unsigned char buf[512], *point;
3167 		int point_len, header_len;
3168 		const int MAX_HEADER_LEN = 3;
3169 		const EC_GROUP *ecgroup = EC_KEY_get0_group(src);
3170 		const EC_POINT *ecpoint = EC_KEY_get0_public_key(src);
3171 		if (!ecgroup || !ecpoint)
3172 			return -1;
3173 		point_len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), NULL);
3174 		gost->public.value = malloc(MAX_HEADER_LEN+point_len);
3175 		if (!gost->public.value)
3176 			return -1;
3177 		point = gost->public.value;
3178 		ASN1_put_object(&point, 0, point_len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
3179 		header_len = point-gost->public.value;
3180 		memcpy(point, buf, point_len);
3181 		gost->public.len = header_len+point_len;
3182 #ifdef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding
3183 		gost->public.len   -= header_len;
3184 		gost->public.value += header_len;
3185 #endif
3186 	}
3187 
3188 	return 0;
3189 }
3190 #endif
3191 #endif
3192 
3193 #define MAX_OBJECT_SIZE	5000
3194 
3195 /* Currently for certificates (-type cert), private keys (-type privkey),
3196    public keys (-type pubkey) and data objects (-type data). */
write_object(CK_SESSION_HANDLE session)3197 static int write_object(CK_SESSION_HANDLE session)
3198 {
3199 	CK_BBOOL _true = TRUE;
3200 	CK_BBOOL _false = FALSE;
3201 	unsigned char contents[MAX_OBJECT_SIZE + 1];
3202 	int contents_len = 0;
3203 	unsigned char certdata[MAX_OBJECT_SIZE];
3204 	int certdata_len = 0;
3205 	FILE *f;
3206 	CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, seckey_obj, data_obj;
3207 	CK_ATTRIBUTE cert_templ[20], privkey_templ[30], pubkey_templ[20], seckey_templ[20], data_templ[20];
3208 	int n_cert_attr = 0, n_privkey_attr = 0, n_pubkey_attr = 0, n_seckey_attr = 0, n_data_attr = 0;
3209 	struct sc_object_id oid;
3210 	CK_RV rv;
3211 	int need_to_parse_certdata = 0;
3212 	unsigned char *oid_buf = NULL;
3213 	CK_OBJECT_CLASS clazz;
3214 	CK_CERTIFICATE_TYPE cert_type;
3215 	CK_KEY_TYPE type = CKK_RSA;
3216 #ifdef ENABLE_OPENSSL
3217 	struct x509cert_info cert;
3218 	struct rsakey_info rsa;
3219 	struct gostkey_info gost;
3220 	EVP_PKEY *evp_key = NULL;
3221 	int pk_type;
3222 
3223 	memset(&cert, 0, sizeof(cert));
3224 	memset(&rsa,  0, sizeof(rsa));
3225 	memset(&gost,  0, sizeof(gost));
3226 #endif
3227 
3228 	memset(contents, 0, sizeof(contents));
3229 	memset(certdata, 0, sizeof(certdata));
3230 
3231 	f = fopen(opt_file_to_write, "rb");
3232 	if (f == NULL)
3233 		util_fatal("Couldn't open file \"%s\"", opt_file_to_write);
3234 	contents_len = fread(contents, 1, sizeof(contents) - 1, f);
3235 	if (contents_len < 0)
3236 		util_fatal("Couldn't read from file \"%s\"", opt_file_to_write);
3237 	fclose(f);
3238 	contents[contents_len] = '\0';
3239 
3240 	if (opt_attr_from_file) {
3241 		if (!(f = fopen(opt_attr_from_file, "rb")))
3242 			util_fatal("Couldn't open file \"%s\"", opt_attr_from_file);
3243 		certdata_len = fread(certdata, 1, sizeof(certdata) - 1, f);
3244 		fclose(f);
3245 		if (certdata_len < 0)
3246 			util_fatal("Couldn't read from file \"%s\"", opt_attr_from_file);
3247 		certdata[certdata_len] = '\0';
3248 		need_to_parse_certdata = 1;
3249 	}
3250 	if (opt_object_class == CKO_CERTIFICATE) {
3251 		if (opt_attr_from_file) {
3252 			/* Convert  contents  from PEM to DER if needed
3253 			 * certdata  already read and will be validated later
3254 			 */
3255 #ifdef ENABLE_OPENSSL
3256 			parse_certificate(NULL, contents, contents_len, contents, &contents_len);
3257 #else
3258 			util_fatal("No OpenSSL support, cannot parse certificate");
3259 #endif
3260 		} else {
3261 			memcpy(certdata, contents, MAX_OBJECT_SIZE);
3262 			certdata_len = contents_len;
3263 			need_to_parse_certdata = 1;
3264 		}
3265 	}
3266 
3267 	if (need_to_parse_certdata) {
3268 #ifdef ENABLE_OPENSSL
3269 		/* Validate and get the certificate fields (from certdata)
3270 		 * and convert PEM to DER if needed
3271 		 */
3272 		parse_certificate(&cert, certdata, certdata_len,
3273 			(opt_attr_from_file ? NULL : contents), &contents_len);
3274 #else
3275 		util_fatal("No OpenSSL support, cannot parse certificate");
3276 #endif
3277 	}
3278 	if (opt_object_class == CKO_PRIVATE_KEY || opt_object_class == CKO_PUBLIC_KEY) {
3279 #ifdef ENABLE_OPENSSL
3280 		int is_private = opt_object_class == CKO_PRIVATE_KEY;
3281 		int rv;
3282 
3283 		rv = do_read_key(contents, contents_len, is_private, &evp_key);
3284 		if (rv) {
3285 			if (is_private)
3286 				util_fatal("Cannot read private key");
3287 			else
3288 				util_fatal("Cannot read public key");
3289 		}
3290 
3291 		pk_type = EVP_PKEY_base_id(evp_key);
3292 
3293 		if (pk_type == EVP_PKEY_RSA)   {
3294 			rv = parse_rsa_pkey(evp_key, is_private, &rsa);
3295 		}
3296 #if !defined(OPENSSL_NO_EC)
3297 		else if (pk_type == NID_id_GostR3410_2001)   {
3298 			rv = parse_gost_pkey(evp_key, is_private, &gost);
3299 			type = CKK_GOSTR3410;
3300 		} else if (pk_type == EVP_PKEY_EC) {
3301 			rv = parse_ec_pkey(evp_key, is_private, &gost);
3302 			type = CKK_EC;
3303 		}
3304 #endif
3305 		else
3306 			util_fatal("Unsupported key type: 0x%X", pk_type);
3307 
3308 		if (rv)
3309 			util_fatal("Cannot parse key");
3310 #else
3311 		util_fatal("No OpenSSL support, cannot parse key");
3312 #endif
3313 	}
3314 
3315 	switch(opt_object_class)
3316 	{
3317 	case CKO_CERTIFICATE:
3318 		clazz = CKO_CERTIFICATE;
3319 		cert_type = CKC_X_509;
3320 
3321 		FILL_ATTR(cert_templ[0], CKA_TOKEN, &_true, sizeof(_true));
3322 		FILL_ATTR(cert_templ[1], CKA_VALUE, contents, contents_len);
3323 		FILL_ATTR(cert_templ[2], CKA_CLASS, &clazz, sizeof(clazz));
3324 		FILL_ATTR(cert_templ[3], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
3325 		FILL_ATTR(cert_templ[4], CKA_PRIVATE, &_false, sizeof(_false));
3326 		n_cert_attr = 5;
3327 
3328 		if (opt_object_label != NULL) {
3329 			FILL_ATTR(cert_templ[n_cert_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label));
3330 			n_cert_attr++;
3331 		}
3332 		if (opt_object_id_len != 0) {
3333 			FILL_ATTR(cert_templ[n_cert_attr], CKA_ID, opt_object_id, opt_object_id_len);
3334 			n_cert_attr++;
3335 		}
3336 #ifdef ENABLE_OPENSSL
3337 		/* according to PKCS #11 CKA_SUBJECT MUST be specified */
3338 		FILL_ATTR(cert_templ[n_cert_attr], CKA_SUBJECT, cert.subject, cert.subject_len);
3339 		n_cert_attr++;
3340 		FILL_ATTR(cert_templ[n_cert_attr], CKA_ISSUER, cert.issuer, cert.issuer_len);
3341 		n_cert_attr++;
3342 		FILL_ATTR(cert_templ[n_cert_attr], CKA_SERIAL_NUMBER, cert.serialnum, cert.serialnum_len);
3343 		n_cert_attr++;
3344 #endif
3345 		break;
3346 	case CKO_PRIVATE_KEY:
3347 		clazz = CKO_PRIVATE_KEY;
3348 
3349 		n_privkey_attr = 0;
3350 		FILL_ATTR(privkey_templ[n_privkey_attr], CKA_CLASS, &clazz, sizeof(clazz));
3351 		n_privkey_attr++;
3352 		FILL_ATTR(privkey_templ[n_privkey_attr], CKA_TOKEN, &_true, sizeof(_true));
3353 		n_privkey_attr++;
3354 		FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PRIVATE, &_true, sizeof(_true));
3355 		n_privkey_attr++;
3356 		FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SENSITIVE, &_true, sizeof(_true));
3357 		n_privkey_attr++;
3358 
3359 		if (opt_object_label != NULL) {
3360 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label));
3361 			n_privkey_attr++;
3362 		}
3363 		if (opt_object_id_len != 0) {
3364 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ID, opt_object_id, opt_object_id_len);
3365 			n_privkey_attr++;
3366 		}
3367 		if (opt_key_usage_sign != 0) {
3368 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true));
3369 			n_privkey_attr++;
3370 		}
3371 		if (opt_key_usage_decrypt != 0) {
3372 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DECRYPT, &_true, sizeof(_true));
3373 			n_privkey_attr++;
3374 		}
3375 		if (opt_key_usage_derive != 0) {
3376 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true));
3377 			n_privkey_attr++;
3378 		}
3379 		if (opt_always_auth != 0) {
3380 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE,
3381 				&_true, sizeof(_true));
3382 			n_privkey_attr++;
3383 		}
3384 		if (opt_is_extractable != 0) {
3385 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EXTRACTABLE, &_true, sizeof(_true));
3386 			n_privkey_attr++;
3387 		}
3388 		if (opt_allowed_mechanisms_len > 0) {
3389 			FILL_ATTR(privkey_templ[n_privkey_attr],
3390 				CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
3391 				sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
3392 			n_privkey_attr++;
3393 		}
3394 
3395 
3396 #ifdef ENABLE_OPENSSL
3397 		if (cert.subject_len != 0) {
3398 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len);
3399 			n_privkey_attr++;
3400 		}
3401 		pk_type = EVP_PKEY_base_id(evp_key);
3402 
3403 		if (pk_type == EVP_PKEY_RSA)   {
3404 			type = CKK_RSA;
3405 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3406 			n_privkey_attr++;
3407 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len);
3408 			n_privkey_attr++;
3409 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len);
3410 			n_privkey_attr++;
3411 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PRIVATE_EXPONENT, rsa.private_exponent, rsa.private_exponent_len);
3412 			n_privkey_attr++;
3413 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PRIME_1, rsa.prime_1, rsa.prime_1_len);
3414 			n_privkey_attr++;
3415 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PRIME_2, rsa.prime_2, rsa.prime_2_len);
3416 			n_privkey_attr++;
3417 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EXPONENT_1, rsa.exponent_1, rsa.exponent_1_len);
3418 			n_privkey_attr++;
3419 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EXPONENT_2, rsa.exponent_2, rsa.exponent_2_len);
3420 			n_privkey_attr++;
3421 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_COEFFICIENT, rsa.coefficient, rsa.coefficient_len);
3422 			n_privkey_attr++;
3423 		}
3424 #if !defined(OPENSSL_NO_EC)
3425 		else if (pk_type == EVP_PKEY_EC)   {
3426 			type = CKK_EC;
3427 
3428 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3429 			n_privkey_attr++;
3430 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len);
3431 			n_privkey_attr++;
3432 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len);
3433 			n_privkey_attr++;
3434 		}
3435 		else if (pk_type == NID_id_GostR3410_2001)   {
3436 			type = CKK_GOSTR3410;
3437 
3438 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3439 			n_privkey_attr++;
3440 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
3441 			n_privkey_attr++;
3442 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len);
3443 			/* CKA_VALUE of the GOST key has to be in the little endian order */
3444 			rv = sc_mem_reverse(privkey_templ[n_privkey_attr].pValue, privkey_templ[n_privkey_attr].ulValueLen);
3445 			if (rv)
3446 				return rv;
3447 			n_privkey_attr++;
3448 		}
3449 
3450 #endif
3451 #endif
3452 		break;
3453 	case CKO_PUBLIC_KEY:
3454 		clazz = CKO_PUBLIC_KEY;
3455 #ifdef ENABLE_OPENSSL
3456 		pk_type = EVP_PKEY_base_id(evp_key);
3457 		if (pk_type == EVP_PKEY_RSA)
3458 			type = CKK_RSA;
3459 #if !defined(OPENSSL_NO_EC)
3460 		else if (pk_type == EVP_PKEY_EC)
3461 			type = CKK_EC;
3462 		else if (pk_type == NID_id_GostR3410_2001)
3463 			type = CKK_GOSTR3410;
3464 #endif
3465 		else
3466 			util_fatal("Unsupported public key type: 0x%X", pk_type);
3467 #endif
3468 
3469 		n_pubkey_attr = 0;
3470 		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_CLASS, &clazz, sizeof(clazz));
3471 		n_pubkey_attr++;
3472 		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_TOKEN, &_true, sizeof(_true));
3473 		n_pubkey_attr++;
3474 
3475 		if (opt_is_private != 0) {
3476 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PRIVATE, &_true, sizeof(_true));
3477 			n_pubkey_attr++;
3478 		}
3479 		else {
3480 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PRIVATE, &_false, sizeof(_false));
3481 			n_pubkey_attr++;
3482 		}
3483 
3484 		if (opt_object_label != NULL) {
3485 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_LABEL,
3486 				opt_object_label, strlen(opt_object_label));
3487 			n_pubkey_attr++;
3488 		}
3489 		if (opt_object_id_len != 0) {
3490 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_ID,
3491 				opt_object_id, opt_object_id_len);
3492 			n_pubkey_attr++;
3493 		}
3494 		if (opt_key_usage_sign != 0) {
3495 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true));
3496 			n_pubkey_attr++;
3497 		}
3498 		if (opt_key_usage_decrypt != 0) {
3499 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_ENCRYPT, &_true, sizeof(_true));
3500 			n_pubkey_attr++;
3501 		}
3502 		if (opt_key_usage_derive != 0) {
3503 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_DERIVE, &_true, sizeof(_true));
3504 			n_pubkey_attr++;
3505 		}
3506 
3507 #ifdef ENABLE_OPENSSL
3508 		if (cert.subject_len != 0) {
3509 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len);
3510 			n_pubkey_attr++;
3511 		}
3512 		pk_type = EVP_PKEY_base_id(evp_key);
3513 
3514 		if (pk_type == EVP_PKEY_RSA) {
3515 			type = CKK_RSA;
3516 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3517 			n_pubkey_attr++;
3518 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS,
3519 				rsa.modulus, rsa.modulus_len);
3520 			n_pubkey_attr++;
3521 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len);
3522 			n_pubkey_attr++;
3523 		}
3524 #if !defined(OPENSSL_NO_EC)
3525 		else if (pk_type == EVP_PKEY_EC)   {
3526 			type = CKK_EC;
3527 
3528 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3529 			n_pubkey_attr++;
3530 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len);
3531 			n_pubkey_attr++;
3532 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, gost.public.value, gost.public.len);
3533 			n_pubkey_attr++;
3534 		}
3535 		else if (pk_type == NID_id_GostR3410_2001) {
3536 			type = CKK_GOSTR3410;
3537 
3538 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
3539 			n_pubkey_attr++;
3540 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
3541 			n_pubkey_attr++;
3542 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, gost.public.value, gost.public.len);
3543 			/* CKA_VALUE of the GOST key has to be in the little endian order */
3544 			rv = sc_mem_reverse(pubkey_templ[n_pubkey_attr].pValue, pubkey_templ[n_pubkey_attr].ulValueLen);
3545 			if (rv)
3546 				return rv;
3547 			n_pubkey_attr++;
3548 		}
3549 #endif
3550 #endif
3551 		break;
3552 	case CKO_SECRET_KEY:
3553 		clazz = CKO_SECRET_KEY;
3554 		type = CKK_GENERIC_SECRET;
3555 
3556 		if (opt_key_type != 0) {
3557 			if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0)
3558 				type = CKK_AES;
3559 			else if (strncasecmp(opt_key_type, "DES3:", strlen("DES3:")) == 0)
3560 				type = CKK_DES3;
3561 			else
3562 				util_fatal("Unknown key type: 0x%lX", type);
3563 		}
3564 
3565 		FILL_ATTR(seckey_templ[0], CKA_CLASS, &clazz, sizeof(clazz));
3566 		FILL_ATTR(seckey_templ[1], CKA_KEY_TYPE, &type, sizeof(type));
3567 		FILL_ATTR(seckey_templ[2], CKA_TOKEN, &_true, sizeof(_true));
3568 		FILL_ATTR(seckey_templ[3], CKA_VALUE, &contents, contents_len);
3569 		n_seckey_attr = 4;
3570 
3571 		if (opt_is_private != 0) {
3572 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_PRIVATE, &_true, sizeof(_true));
3573 			n_seckey_attr++;
3574 		}
3575 		else {
3576 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_PRIVATE, &_false, sizeof(_false));
3577 			n_seckey_attr++;
3578 		}
3579 
3580 		if (opt_is_sensitive != 0) {
3581 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SENSITIVE, &_true, sizeof(_true));
3582 			n_seckey_attr++;
3583 		}
3584 		else {
3585 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SENSITIVE, &_false, sizeof(_false));
3586 			n_seckey_attr++;
3587 		}
3588 		if (opt_is_extractable != 0) {
3589 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_EXTRACTABLE, &_true, sizeof(_true));
3590 			n_seckey_attr++;
3591 		}
3592 		else {
3593 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_EXTRACTABLE, &_false, sizeof(_false));
3594 			n_seckey_attr++;
3595 		}
3596 
3597 		if (opt_object_label != NULL) {
3598 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label));
3599 			n_seckey_attr++;
3600 		}
3601 		if (opt_object_id_len != 0)  {
3602 			FILL_ATTR(seckey_templ[n_seckey_attr], CKA_ID, opt_object_id, opt_object_id_len);
3603 			n_seckey_attr++;
3604 		}
3605 		break;
3606 	case CKO_DATA:
3607 		clazz = CKO_DATA;
3608 		FILL_ATTR(data_templ[0], CKA_CLASS, &clazz, sizeof(clazz));
3609 		FILL_ATTR(data_templ[1], CKA_TOKEN, &_true, sizeof(_true));
3610 		FILL_ATTR(data_templ[2], CKA_VALUE, &contents, contents_len);
3611 
3612 		n_data_attr = 3;
3613 
3614 		if (opt_is_private != 0) {
3615 			FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE, &_true, sizeof(_true));
3616 			n_data_attr++;
3617 		}
3618 		else {
3619 			FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE, &_false, sizeof(_false));
3620 			n_data_attr++;
3621 		}
3622 
3623 		if (opt_application_label != NULL) {
3624 			FILL_ATTR(data_templ[n_data_attr], CKA_APPLICATION,
3625 				opt_application_label, strlen(opt_application_label));
3626 			n_data_attr++;
3627 		}
3628 
3629 		if (opt_application_id != NULL) {
3630 			size_t len;
3631 
3632 			if (sc_format_oid(&oid, opt_application_id))
3633 				util_fatal("Invalid OID \"%s\"", opt_application_id);
3634 
3635 			if (sc_asn1_encode_object_id(&oid_buf, &len, &oid))
3636 				util_fatal("Cannot encode OID \"%s\"", opt_application_id);
3637 
3638 			FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID, oid_buf, len);
3639 			n_data_attr++;
3640 		}
3641 
3642 		if (opt_object_label != NULL) {
3643 			FILL_ATTR(data_templ[n_data_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label));
3644 			n_data_attr++;
3645 		}
3646 		break;
3647 	default:
3648 		util_fatal("Writing of a \"%s\" type not (yet) supported", opt_object_class_str);
3649 		break;
3650 	}
3651 
3652 	if (n_data_attr) {
3653 		rv = p11->C_CreateObject(session, data_templ, n_data_attr, &data_obj);
3654 		if (rv != CKR_OK)
3655 			p11_fatal("C_CreateObject", rv);
3656 
3657 		printf("Created Data Object:\n");
3658 		show_dobj(session, data_obj);
3659 	}
3660 	if (n_cert_attr) {
3661 		rv = p11->C_CreateObject(session, cert_templ, n_cert_attr, &cert_obj);
3662 		if (rv != CKR_OK)
3663 			p11_fatal("C_CreateObject", rv);
3664 
3665 		printf("Created certificate:\n");
3666 		show_object(session, cert_obj);
3667 	}
3668 
3669 	if (n_pubkey_attr) {
3670 		rv = p11->C_CreateObject(session, pubkey_templ, n_pubkey_attr, &pubkey_obj);
3671 		if (rv != CKR_OK)
3672 			p11_fatal("C_CreateObject", rv);
3673 
3674 		printf("Created public key:\n");
3675 		show_object(session, pubkey_obj);
3676 	}
3677 
3678 	if (n_privkey_attr) {
3679 		rv = p11->C_CreateObject(session, privkey_templ, n_privkey_attr, &privkey_obj);
3680 		if (rv != CKR_OK)
3681 			p11_fatal("C_CreateObject", rv);
3682 
3683 		printf("Created private key:\n");
3684 		show_object(session, privkey_obj);
3685 	}
3686 
3687 	if (n_seckey_attr) {
3688 		rv = p11->C_CreateObject(session, seckey_templ, n_seckey_attr, &seckey_obj);
3689 		if (rv != CKR_OK)
3690 			p11_fatal("C_CreateObject", rv);
3691 
3692 		printf("Created secret key:\n");
3693 		show_object(session, seckey_obj);
3694 	}
3695 
3696 	if (oid_buf)
3697 		free(oid_buf);
3698 	return 1;
3699 }
3700 
set_id_attr(CK_SESSION_HANDLE session)3701 static void set_id_attr(CK_SESSION_HANDLE session)
3702 {
3703 	CK_OBJECT_HANDLE obj;
3704 	CK_ATTRIBUTE templ[] = {{CKA_ID, new_object_id, new_object_id_len}};
3705 	CK_RV rv;
3706 
3707 	if (!find_object(session, opt_object_class, &obj, opt_object_id, opt_object_id_len, 0)) {
3708 		fprintf(stderr, "set_id(): couldn't find the object\n");
3709 		return;
3710 	}
3711 
3712 	rv = p11->C_SetAttributeValue(session, obj, templ, 1);
3713 	if (rv != CKR_OK)
3714 		p11_fatal("C_SetAttributeValue", rv);
3715 
3716 	printf("Result:");
3717 	show_object(session, obj);
3718 }
3719 
find_slot_by_description(const char * label,CK_SLOT_ID_PTR result)3720 static int find_slot_by_description(const char *label, CK_SLOT_ID_PTR result)
3721 {
3722 	CK_SLOT_INFO	info;
3723 	CK_ULONG	n, len;
3724 	CK_RV		rv;
3725 
3726 	if (!p11_num_slots)
3727 		return 0;
3728 
3729 	len = strlen(label);
3730 	for (n = 0; n < p11_num_slots; n++) {
3731 		const char	*slot_label;
3732 
3733 		rv = p11->C_GetSlotInfo(p11_slots[n], &info);
3734 		if (rv != CKR_OK)
3735 			continue;
3736 		slot_label = p11_utf8_to_local(info.slotDescription, sizeof(info.slotDescription));
3737 		if (!strncmp(label, slot_label, len)) {
3738 			*result = p11_slots[n];
3739 			return 1;
3740 		}
3741 	}
3742 	return 0;
3743 }
3744 
find_slot_by_token_label(const char * label,CK_SLOT_ID_PTR result)3745 static int find_slot_by_token_label(const char *label, CK_SLOT_ID_PTR result)
3746 {
3747 	CK_TOKEN_INFO	info;
3748 	CK_ULONG	n, len;
3749 	CK_RV		rv;
3750 
3751 	if (!p11_num_slots)
3752 		return 0;
3753 
3754 	len = strlen(label);
3755 	for (n = 0; n < p11_num_slots; n++) {
3756 		const char	*token_label;
3757 
3758 		rv = p11->C_GetTokenInfo(p11_slots[n], &info);
3759 		if (rv != CKR_OK)
3760 			continue;
3761 		token_label = p11_utf8_to_local(info.label, sizeof(info.label));
3762 		if (!strncmp(label, token_label, len)) {
3763 			*result = p11_slots[n];
3764 			return 1;
3765 		}
3766 	}
3767 	return 0;
3768 }
3769 
3770 
find_object(CK_SESSION_HANDLE sess,CK_OBJECT_CLASS cls,CK_OBJECT_HANDLE_PTR ret,const unsigned char * id,size_t id_len,int obj_index)3771 static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls,
3772 		CK_OBJECT_HANDLE_PTR ret,
3773 		const unsigned char *id, size_t id_len, int obj_index)
3774 {
3775 	CK_ATTRIBUTE attrs[2];
3776 	unsigned int nattrs = 0;
3777 	CK_ULONG count;
3778 	CK_RV rv;
3779 	int i;
3780 
3781 	attrs[0].type = CKA_CLASS;
3782 	attrs[0].pValue = &cls;
3783 	attrs[0].ulValueLen = sizeof(cls);
3784 	nattrs++;
3785 	if (id) {
3786 		attrs[nattrs].type = CKA_ID;
3787 		attrs[nattrs].pValue = (void *) id;
3788 		attrs[nattrs].ulValueLen = id_len;
3789 		nattrs++;
3790 	}
3791 
3792 	rv = p11->C_FindObjectsInit(sess, attrs, nattrs);
3793 	if (rv != CKR_OK)
3794 		p11_fatal("C_FindObjectsInit", rv);
3795 
3796 	for (i = 0; i < obj_index; i++) {
3797 		rv = p11->C_FindObjects(sess, ret, 1, &count);
3798 		if (rv != CKR_OK)
3799 			p11_fatal("C_FindObjects", rv);
3800 		if (count == 0)
3801 			goto done;
3802 	}
3803 	rv = p11->C_FindObjects(sess, ret, 1, &count);
3804 	if (rv != CKR_OK)
3805 		p11_fatal("C_FindObjects", rv);
3806 
3807 done:	if (count == 0)
3808 		*ret = CK_INVALID_HANDLE;
3809 	p11->C_FindObjectsFinal(sess);
3810 
3811 	return count;
3812 }
3813 
find_object_with_attributes(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE * out,CK_ATTRIBUTE * attrs,CK_ULONG attrsLen,CK_ULONG obj_index)3814 static CK_RV find_object_with_attributes(CK_SESSION_HANDLE session,
3815 			CK_OBJECT_HANDLE *out,
3816 			CK_ATTRIBUTE *attrs, CK_ULONG attrsLen,
3817 			CK_ULONG obj_index)
3818 {
3819 	CK_ULONG count, ii;
3820 	CK_OBJECT_HANDLE ret;
3821 	CK_RV rv;
3822 
3823 	if (!out || !attrs || !attrsLen)
3824 		return CKR_ARGUMENTS_BAD;
3825 	else
3826 		*out = CK_INVALID_HANDLE;
3827 
3828 	rv = p11->C_FindObjectsInit(session, attrs, attrsLen);
3829 	if (rv != CKR_OK)
3830 		return rv;
3831 
3832 	for (ii = 0; ii < obj_index; ii++) {
3833 		rv = p11->C_FindObjects(session, &ret, 1, &count);
3834 		if (rv != CKR_OK)
3835 			return rv;
3836 		else if (!count)
3837 			goto done;
3838 	}
3839 
3840 	rv = p11->C_FindObjects(session, &ret, 1, &count);
3841 	if (rv != CKR_OK)
3842 		return rv;
3843 	else if (count)
3844 		*out = ret;
3845 
3846 done:
3847 	p11->C_FindObjectsFinal(session);
3848 	return CKR_OK;
3849 }
3850 
3851 
3852 static int
find_mechanism(CK_SLOT_ID slot,CK_FLAGS flags,CK_MECHANISM_TYPE_PTR list,size_t list_len,CK_MECHANISM_TYPE_PTR result)3853 find_mechanism(CK_SLOT_ID slot, CK_FLAGS flags,
3854 		CK_MECHANISM_TYPE_PTR list, size_t list_len,
3855 		CK_MECHANISM_TYPE_PTR result)
3856 {
3857 	CK_MECHANISM_TYPE *mechs = NULL;
3858 	CK_ULONG	count = 0;
3859 
3860 	count = get_mechanisms(slot, &mechs, flags);
3861 	if (count)   {
3862 		if (list && list_len)   {
3863 			unsigned ii = list_len, jj;
3864 
3865 			for (jj=0; jj<count; jj++)   {
3866 				for (ii=0; ii<list_len; ii++)
3867 					if (*(mechs + jj) == *(list + ii))
3868 						break;
3869 				if (ii<list_len)
3870 					break;
3871 			}
3872 
3873 			if (jj < count && ii < list_len)
3874 				*result = mechs[jj];
3875 			else
3876 				count = 0;
3877 		}
3878 		else   {
3879 			*result = mechs[0];
3880 		}
3881 	}
3882 	free(mechs);
3883 
3884 	return count;
3885 }
3886 
3887 
list_objects(CK_SESSION_HANDLE sess,CK_OBJECT_CLASS object_class)3888 static void list_objects(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS  object_class)
3889 {
3890 	CK_OBJECT_HANDLE object;
3891 	CK_ULONG count;
3892 	CK_RV rv;
3893 
3894 	rv = p11->C_FindObjectsInit(sess, NULL, 0);
3895 	if (rv != CKR_OK)
3896 		p11_fatal("C_FindObjectsInit", rv);
3897 
3898 	while (1) {
3899 		rv = p11->C_FindObjects(sess, &object, 1, &count);
3900 		if (rv != CKR_OK)
3901 			p11_fatal("C_FindObjects", rv);
3902 		if (count == 0)
3903 			break;
3904 		if ((int) object_class == -1 || object_class == getCLASS(sess, object))
3905 			show_object(sess, object);
3906 	}
3907 	p11->C_FindObjectsFinal(sess);
3908 }
3909 
show_object(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj)3910 static void show_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
3911 {
3912 	CK_OBJECT_CLASS	cls = getCLASS(sess, obj);
3913 
3914 	switch (cls) {
3915 	case CKO_PUBLIC_KEY:
3916 	case CKO_PRIVATE_KEY:
3917 	case CKO_SECRET_KEY:
3918 		show_key(sess, obj);
3919 		break;
3920 	case CKO_CERTIFICATE:
3921 		show_cert(sess, obj);
3922 		break;
3923 	case CKO_DATA:
3924 		show_dobj(sess, obj);
3925 		break;
3926 	case CKO_PROFILE:
3927 		show_profile(sess, obj);
3928 		break;
3929 	default:
3930 		printf("Object %u, type %u\n",
3931 				(unsigned int) obj,
3932 				(unsigned int) cls);
3933 	}
3934 }
3935 
3936 
3937 static CK_OBJECT_HANDLE
derive_ec_key(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key,CK_MECHANISM_TYPE mech_mech)3938 derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE mech_mech)
3939 {
3940 #if defined(ENABLE_OPENSSL) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
3941 	CK_MECHANISM mech;
3942 	CK_OBJECT_CLASS newkey_class= CKO_SECRET_KEY;
3943 	CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET;
3944 	CK_BBOOL true = TRUE;
3945 	CK_BBOOL false = FALSE;
3946 	CK_OBJECT_HANDLE newkey = 0;
3947 	CK_ATTRIBUTE newkey_template[20] = {
3948 		{CKA_TOKEN, &false, sizeof(false)}, /* session only object */
3949 		{CKA_CLASS, &newkey_class, sizeof(newkey_class)},
3950 		{CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)},
3951 		{CKA_SENSITIVE, &false, sizeof(false)},
3952 		{CKA_EXTRACTABLE, &true, sizeof(true)},
3953 		{CKA_ENCRYPT, &true, sizeof(true)},
3954 		{CKA_DECRYPT, &true, sizeof(true)},
3955 		{CKA_WRAP, &true, sizeof(true)},
3956 		{CKA_UNWRAP, &true, sizeof(true)}
3957 	};
3958 	int n_attrs = 9;
3959 	CK_ECDH1_DERIVE_PARAMS ecdh_parms;
3960 	CK_RV rv;
3961 	BIO *bio_in = NULL;
3962 	EC_KEY  *eckey = NULL;
3963 	const EC_GROUP *ecgroup = NULL;
3964 	const EC_POINT *ecpoint = NULL;
3965 	unsigned char *buf = NULL;
3966 	size_t buf_size = 0;
3967 	CK_ULONG key_len = 0;
3968 	ASN1_OCTET_STRING *octet = NULL;
3969 	unsigned char * der = NULL;
3970 	unsigned char * derp = NULL;
3971 	size_t  der_size = 0;
3972 
3973 	printf("Using derive algorithm 0x%8.8lx %s\n", opt_mechanism, p11_mechanism_to_name(mech_mech));
3974 	memset(&mech, 0, sizeof(mech));
3975 	mech.mechanism = mech_mech;
3976 
3977 	/*  Use OpenSSL to read the other public key, and get the raw version */
3978 	bio_in = BIO_new(BIO_s_file());
3979 	if (BIO_read_filename(bio_in, opt_input) <= 0)
3980 		util_fatal("Cannot open %s: %m", opt_input);
3981 
3982 	eckey = d2i_EC_PUBKEY_bio(bio_in, NULL);
3983 	if (!eckey)
3984 		util_fatal("Cannot read EC key from %s", opt_input);
3985 
3986 	ecpoint = EC_KEY_get0_public_key(eckey);
3987 	ecgroup = EC_KEY_get0_group(eckey);
3988 
3989 	if (!ecpoint || !ecgroup)
3990 		util_fatal("Failed to parse other EC key from %s", opt_input);
3991 
3992 	/* both eckeys must be same curve */
3993 	key_len = (EC_GROUP_get_degree(ecgroup) + 7) / 8;
3994 	FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len));
3995 	n_attrs++;
3996 
3997 	if (opt_allowed_mechanisms_len > 0) {
3998 		FILL_ATTR(newkey_template[n_attrs],
3999 			CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
4000 			sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
4001 		n_attrs++;
4002 	}
4003 
4004 	buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL,	    0, NULL);
4005 	buf = (unsigned char *)malloc(buf_size);
4006 	if (buf == NULL)
4007 	    util_fatal("malloc() failure\n");
4008 	buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL);
4009 
4010 	if (opt_derive_pass_der) {
4011 		octet = ASN1_OCTET_STRING_new();
4012 		if (octet == NULL)
4013 		    util_fatal("ASN1_OCTET_STRING_new failure\n");
4014 		ASN1_OCTET_STRING_set(octet, buf, buf_size);
4015 		der_size = i2d_ASN1_OCTET_STRING(octet, NULL);
4016 		derp = der = (unsigned char *) malloc(der_size);
4017 		if (der == NULL)
4018 			util_fatal("malloc() failure\n");
4019 		der_size = i2d_ASN1_OCTET_STRING(octet, &derp);
4020 	}
4021 
4022 	BIO_free(bio_in);
4023 	EC_KEY_free(eckey);
4024 
4025 	memset(&ecdh_parms, 0, sizeof(ecdh_parms));
4026 	ecdh_parms.kdf = CKD_NULL;
4027 	ecdh_parms.ulSharedDataLen = 0;
4028 	ecdh_parms.pSharedData = NULL;
4029 	if (opt_derive_pass_der) {
4030 		ecdh_parms.ulPublicDataLen = der_size;
4031 		ecdh_parms.pPublicData = der;
4032 	} else {
4033 		ecdh_parms.ulPublicDataLen = buf_size;
4034 		ecdh_parms.pPublicData = buf;
4035 	}
4036 	mech.pParameter = &ecdh_parms;
4037 	mech.ulParameterLen = sizeof(ecdh_parms);
4038 
4039 	rv = p11->C_DeriveKey(session, &mech, key, newkey_template, n_attrs, &newkey);
4040 	if (rv != CKR_OK)
4041 	    p11_fatal("C_DeriveKey", rv);
4042 
4043 	free(der);
4044 	free(buf);
4045 	if (octet)
4046 	    ASN1_OCTET_STRING_free(octet);
4047 
4048 	return newkey;
4049 #else
4050 	util_fatal("Derive EC key not supported");
4051 	return 0;
4052 #endif /* ENABLE_OPENSSL  && !OPENSSL_NO_EC && !OPENSSL_NO_ECDSA */
4053 }
4054 
4055 
4056 static void
derive_key(CK_SLOT_ID slot,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key)4057 derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
4058 {
4059 	CK_BYTE *value = NULL;
4060 	CK_ULONG value_len = 0;
4061 	CK_OBJECT_HANDLE derived_key = 0;
4062 	int rv, fd;
4063 
4064 	if (!opt_mechanism_used)
4065 		if (!find_mechanism(slot, CKF_DERIVE|opt_allow_sw, NULL, 0, &opt_mechanism))
4066 			util_fatal("Derive mechanism not supported");
4067 
4068 	switch(opt_mechanism) {
4069 	case CKM_ECDH1_COFACTOR_DERIVE:
4070 	case CKM_ECDH1_DERIVE:
4071 		derived_key= derive_ec_key(session, key, opt_mechanism);
4072 		break;
4073 	default:
4074 		util_fatal("mechanism not supported for derive");
4075 		break;
4076 	}
4077 
4078 	value = getVALUE(session, derived_key, &value_len);
4079 	if (value && value_len > 0) {
4080 		fd = STDOUT_FILENO;
4081 		if (opt_output)   {
4082 			fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR);
4083 			if (fd < 0)
4084 				util_fatal("failed to open %s: %m", opt_output);
4085 		}
4086 
4087 		rv = write(fd, value, value_len);
4088 		if (rv < 0)
4089 			util_fatal("Failed to write to %s: %m", opt_output);
4090 
4091 		if (opt_output)
4092 			close(fd);
4093 	}
4094 }
4095 
4096 
4097 static void
show_key(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj)4098 show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
4099 {
4100 	CK_MECHANISM_TYPE_PTR mechs = NULL;
4101 	CK_KEY_TYPE	key_type = getKEY_TYPE(sess, obj);
4102 	CK_ULONG	size = 0;
4103 	unsigned char	*id, *oid, *value;
4104 	const char      *sepa;
4105 	char		*label;
4106 	int		pub = 1;
4107 	int		sec = 0;
4108 
4109 	switch(getCLASS(sess, obj)) {
4110 		case CKO_PRIVATE_KEY:
4111 			printf("Private Key Object");
4112 			pub = 0;
4113 			break;
4114 		case CKO_PUBLIC_KEY:
4115 			printf("Public Key Object");
4116 			pub = 1;
4117 			break;
4118 		case CKO_SECRET_KEY:
4119 			printf("Secret Key Object");
4120 			sec = 1;
4121 			break;
4122 		default:
4123 			return;
4124 	}
4125 
4126 	switch (key_type) {
4127 	case CKK_RSA:
4128 		if (sec) {
4129 			/* uninitialized secret key (type 0) */
4130 			printf("\n");
4131 		} else {
4132 			if (pub)
4133 				printf("; RSA %lu bits\n",
4134 						(unsigned long) getMODULUS_BITS(sess, obj));
4135 			else
4136 				printf("; RSA \n");
4137 		}
4138 		break;
4139 	case CKK_GOSTR3410:
4140 	case CKK_GOSTR3410_512:
4141 		oid = getGOSTR3411_PARAMS(sess, obj, &size);
4142 		if (oid) {
4143 			if (size == GOST_HASH2001_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2001_PARAMSET_OID.value, size))
4144 				printf("; GOSTR3410\n");
4145 			else if (size == GOST_HASH2012_256_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2012_256_PARAMSET_OID.value, size))
4146 				printf("; GOSTR3410-2012-256\n");
4147 			else if (size == GOST_HASH2012_512_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2012_512_PARAMSET_OID.value, size))
4148 				printf("; GOSTR3410-2012-512\n");
4149 			else
4150 				printf("; unknown GOSTR3410 algorithm\n");
4151 			free(oid);
4152 		} else {
4153 			printf("; unknown GOSTR3410 algorithm\n");
4154 		}
4155 
4156 		oid = getGOSTR3410_PARAMS(sess, obj, &size);
4157 		if (oid) {
4158 			unsigned int	n;
4159 
4160 			printf("  PARAMS OID: ");
4161 			for (n = 0; n < size; n++)
4162 				printf("%02x", oid[n]);
4163 			printf("\n");
4164 			free(oid);
4165 		}
4166 
4167 		if (pub)   {
4168 			value = getVALUE(sess, obj, &size);
4169 			if (value) {
4170 				unsigned int	n;
4171 
4172 				printf("  VALUE:      ");
4173 				for (n = 0; n < size; n++)   {
4174 					if (n && (n%32)==0)
4175 						printf("\n              ");
4176 					printf("%02x", value[n]);
4177 				}
4178 				printf("\n");
4179 				free(value);
4180 			}
4181 		}
4182 		break;
4183 	case CKK_EC_EDWARDS:
4184 	case CKK_EC_MONTGOMERY:
4185 		if (key_type == CKK_EC_EDWARDS) {
4186 			printf("; EC_EDWARDS");
4187 		} else {
4188 			printf("; EC_MONTGOMERY");
4189 		}
4190 		if (pub) {
4191 			unsigned char *bytes = NULL;
4192 			int ksize;
4193 			unsigned int n;
4194 
4195 			bytes = getEC_POINT(sess, obj, &size);
4196 			ksize = 255; /* for now, we support only 255b curves */
4197 
4198 			printf("  EC_POINT %u bits\n", ksize);
4199 			if (bytes) {
4200 				if ((CK_LONG)size > 0) { /* Will print the point here */
4201 					printf("  EC_POINT:   ");
4202 					for (n = 0; n < size; n++)
4203 						printf("%02x", bytes[n]);
4204 					printf("\n");
4205 				}
4206 				free(bytes);
4207 			}
4208 			bytes = NULL;
4209 			bytes = getEC_PARAMS(sess, obj, &size);
4210 			if (bytes){
4211 				if ((CK_LONG)size > 0) {
4212 					struct sc_object_id oid;
4213 
4214 					printf("  EC_PARAMS:  ");
4215 					for (n = 0; n < size; n++)
4216 						printf("%02x", bytes[n]);
4217 
4218 					sc_init_oid(&oid);
4219 					if (size > 2 && sc_asn1_decode_object_id(bytes + 2, size - 2, &oid) == SC_SUCCESS) {
4220 						printf(" (OID %i", oid.value[0]);
4221 						if (oid.value[0] >= 0)
4222 							for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS)
4223 									&& (oid.value[n] >= 0); n++)
4224 								printf(".%i", oid.value[n]);
4225 						printf(")");
4226 					}
4227 					printf("\n");
4228 
4229 				}
4230 				free(bytes);
4231 			}
4232 		} else {
4233 			printf("\n");
4234 		}
4235 		break;
4236 	case CKK_EC:
4237 		printf("; EC");
4238 		if (pub) {
4239 			unsigned char *bytes = NULL;
4240 			unsigned int n;
4241 			int ksize;
4242 
4243 			bytes = getEC_POINT(sess, obj, &size);
4244 			/*
4245 			 * (We only support uncompressed for now)
4246 			 * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y"
4247 			 * So a "256" bit key has x and y of 32 bytes each
4248 			 * something like: "04 41 04||x||y"
4249 			 * Do simple size calculation based on DER encoding
4250 			 */
4251 			if ((size - 2) <= 127)
4252 				ksize = (size - 3) * 4;
4253 			else if ((size - 3) <= 255)
4254 				ksize = (size - 4) * 4;
4255 			else
4256 				ksize = (size - 5) * 4;
4257 
4258 			printf("  EC_POINT %d bits\n", ksize);
4259 			if (bytes) {
4260 				if ((CK_LONG)size > 0) { /* Will print the point here */
4261 					printf("  EC_POINT:   ");
4262 					for (n = 0; n < size; n++)
4263 						printf("%02x", bytes[n]);
4264 					printf("\n");
4265 				}
4266 				free(bytes);
4267 			}
4268 			bytes = NULL;
4269 			bytes = getEC_PARAMS(sess, obj, &size);
4270 			if (bytes){
4271 				if ((CK_LONG)size > 0) {
4272 					printf("  EC_PARAMS:  ");
4273 					for (n = 0; n < size; n++)
4274 						printf("%02x", bytes[n]);
4275 					printf("\n");
4276 				}
4277 				free(bytes);
4278 			}
4279 		} else
4280 			printf("\n");
4281 		break;
4282 	case CKK_GENERIC_SECRET:
4283 	case CKK_AES:
4284 	case CKK_DES:
4285 	case CKK_DES3:
4286 		if (key_type == CKK_AES)
4287 			printf("; AES");
4288 		else if (key_type == CKK_DES)
4289 			printf("; DES");
4290 		else if (key_type == CKK_DES3)
4291 			printf("; DES3");
4292 		else
4293 			printf("; Generic secret");
4294 		size = getVALUE_LEN(sess, obj);
4295 		if (size)
4296 			printf(" length %li", size);
4297 		size = 0;
4298 		printf("\n");
4299 		value = getVALUE(sess, obj, &size);
4300 		if (value) {
4301 			unsigned int    n;
4302 
4303 			printf("  VALUE:      ");
4304 			for (n = 0; n < size; n++)   {
4305 				if (n && (n%32)==0)
4306 					printf("\n              ");
4307 				printf("%02x", value[n]);
4308 			}
4309 			printf("\n");
4310 			free(value);
4311 		}
4312 		break;
4313 	default:
4314 		printf("; unknown key algorithm %lu\n",
4315 				(unsigned long) key_type);
4316 		break;
4317 	}
4318 
4319 	if ((label = getLABEL(sess, obj, NULL)) != NULL) {
4320 		printf("  label:      %s\n", label);
4321 		free(label);
4322 	}
4323 
4324 	if ((id = getID(sess, obj, &size)) != NULL && size) {
4325 		unsigned int	n;
4326 
4327 		printf("  ID:         ");
4328 		for (n = 0; n < size; n++)
4329 			printf("%02x", id[n]);
4330 		printf("\n");
4331 		free(id);
4332 	}
4333 
4334 	printf("  Usage:      ");
4335 	sepa = "";
4336 	if ((pub || sec) && getENCRYPT(sess, obj)) {
4337 		printf("%sencrypt", sepa);
4338 		sepa = ", ";
4339 	}
4340 	if ((!pub || sec) && getDECRYPT(sess, obj)) {
4341 		printf("%sdecrypt", sepa);
4342 		sepa = ", ";
4343 	}
4344 	if (!pub && getSIGN(sess, obj)) {
4345 		printf("%ssign", sepa);
4346 		sepa = ", ";
4347 	}
4348 
4349 	suppress_warn = 1;
4350 	if (!pub && getOPENSC_NON_REPUDIATION(sess, obj)) {
4351 		printf("%snon-repudiation", sepa);
4352 		sepa = ", ";
4353 	}
4354 	suppress_warn = 0;
4355 
4356 	if (pub && getVERIFY(sess, obj)) {
4357 		printf("%sverify", sepa);
4358 		sepa = ", ";
4359 	}
4360 	if ((pub || sec) && getWRAP(sess, obj)) {
4361 		printf("%swrap", sepa);
4362 		sepa = ", ";
4363 	}
4364 	if ((!pub || sec) && getUNWRAP(sess, obj)) {
4365 		printf("%sunwrap", sepa);
4366 		sepa = ", ";
4367 	}
4368 	if (getDERIVE(sess, obj)) {
4369 		printf("%sderive", sepa);
4370 		sepa = ", ";
4371 	}
4372 	if (!*sepa)
4373 		printf("none");
4374 	printf("\n");
4375 
4376 	printf("  Access:     ");
4377 	sepa = "";
4378 	if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) {
4379 		printf("%salways authenticate", sepa);
4380 		sepa = ", ";
4381 	}
4382 	if (!pub || sec) {
4383 		if (getSENSITIVE(sess, obj)) {
4384 			printf("%ssensitive", sepa);
4385 			sepa = ", ";
4386 		}
4387 		if (getALWAYS_SENSITIVE(sess, obj)) {
4388 			printf("%salways sensitive", sepa);
4389 			sepa = ", ";
4390 		}
4391 		if (getEXTRACTABLE(sess, obj)) {
4392 			printf("%sextractable", sepa);
4393 			sepa = ", ";
4394 		}
4395 		if (getNEVER_EXTRACTABLE(sess, obj)) {
4396 			printf("%snever extractable", sepa);
4397 			sepa = ", ";
4398 		}
4399 	}
4400 	if (getLOCAL(sess, obj)) {
4401 		printf("%slocal", sepa);
4402 		sepa = ", ";
4403 	}
4404 	if (!*sepa)
4405 		printf("none");
4406 	printf("\n");
4407 
4408 	if (!pub) {
4409 		mechs = getALLOWED_MECHANISMS(sess, obj, &size);
4410 		if (mechs && size) {
4411 			unsigned int n;
4412 
4413 			printf("  Allowed mechanisms: ");
4414 			for (n = 0; n < size; n++) {
4415 				printf("%s%s", (n != 0 ? "," : ""),
4416 					p11_mechanism_to_name(mechs[n]));
4417 			}
4418 			printf("\n");
4419 		}
4420 	}
4421 
4422 	suppress_warn = 0;
4423 }
4424 
show_cert(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj)4425 static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
4426 {
4427 	CK_CERTIFICATE_TYPE	cert_type = getCERTIFICATE_TYPE(sess, obj);
4428 	CK_ULONG	size;
4429 	unsigned char	*id;
4430 	char		*label;
4431 #if defined(ENABLE_OPENSSL)
4432 	unsigned char	*subject;
4433 #endif /* ENABLE_OPENSSL */
4434 
4435 	printf("Certificate Object; type = ");
4436 	switch (cert_type) {
4437 	case CKC_X_509:
4438 		printf("X.509 cert\n");
4439 		break;
4440 	case CKC_X_509_ATTR_CERT:
4441 		printf("X.509 attribute cert\n");
4442 		break;
4443 	case CKC_VENDOR_DEFINED:
4444 		printf("vendor defined\n");
4445 		break;
4446 	default:
4447 		printf("unknown cert type\n");
4448 		break;
4449 	}
4450 
4451 	if ((label = getLABEL(sess, obj, NULL)) != NULL) {
4452 		printf("  label:      %s\n", label);
4453 		free(label);
4454 	}
4455 
4456 #if defined(ENABLE_OPENSSL)
4457 	if ((subject = getSUBJECT(sess, obj, &size)) != NULL) {
4458 		X509_NAME *name;
4459 		const unsigned char *tmp = subject;
4460 
4461 		name = d2i_X509_NAME(NULL, &tmp, size);
4462 		if(name) {
4463 			BIO *bio = BIO_new(BIO_s_file());
4464 			BIO_set_fp(bio, stdout, BIO_NOCLOSE);
4465 			printf("  subject:    DN: ");
4466 			X509_NAME_print(bio, name, XN_FLAG_RFC2253);
4467 			printf("\n");
4468 			BIO_free(bio);
4469 		}
4470 		free(subject);
4471 	}
4472 #endif /* ENABLE_OPENSSL */
4473 
4474 	if ((id = getID(sess, obj, &size)) != NULL && size) {
4475 		unsigned int	n;
4476 
4477 		printf("  ID:         ");
4478 		for (n = 0; n < size; n++)
4479 			printf("%02x", id[n]);
4480 		printf("\n");
4481 		free(id);
4482 	}
4483 }
4484 
show_dobj(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj)4485 static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
4486 {
4487 	unsigned char *oid_buf;
4488 	char *label;
4489 	CK_ULONG    size = 0;
4490 
4491 	suppress_warn = 1;
4492 	printf("Data object %u\n", (unsigned int) obj);
4493 	printf("  label:          ");
4494 	if ((label = getLABEL(sess, obj, NULL)) != NULL) {
4495 		printf("'%s'\n", label);
4496 		free(label);
4497 	}
4498 	else   {
4499 		printf("<empty>\n");
4500 	}
4501 
4502 	printf("  application:    ");
4503 	if ((label = getAPPLICATION(sess, obj, NULL)) != NULL) {
4504 		printf("'%s'\n", label);
4505 		free(label);
4506 	}
4507 	else   {
4508 		printf("<empty>\n");
4509 	}
4510 
4511 	printf("  app_id:         ");
4512 	oid_buf = getOBJECT_ID(sess, obj, &size);
4513 	if (oid_buf != NULL && size) {
4514 		unsigned int	n;
4515 		struct sc_object_id oid;
4516 
4517 		sc_init_oid(&oid);
4518 		sc_asn1_decode_object_id(oid_buf, size, &oid);
4519 		printf("%i", oid.value[0]);
4520 		if (oid.value[0] >= 0)
4521 			for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[n] >= 0); n++)
4522 				printf(".%i", oid.value[n]);
4523 		printf("\n");
4524 
4525 		free(oid_buf);
4526 	}
4527 	else   {
4528 		printf("<empty>\n");
4529 	}
4530 
4531 	printf("  flags:          ");
4532 	if (getMODIFIABLE(sess, obj))
4533 		printf(" modifiable");
4534 	if (getPRIVATE(sess, obj))
4535 		printf(" private");
4536 	if (!getMODIFIABLE(sess, obj) && !getPRIVATE(sess, obj))
4537 		printf("<empty>");
4538 
4539 	printf ("\n");
4540 	suppress_warn = 0;
4541 }
4542 
4543 
show_profile(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj)4544 static void show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
4545 {
4546 	CK_ULONG    id = 0;
4547 
4548 	printf("Profile object %u\n", (unsigned int) obj);
4549 	printf("  profile_id:          ");
4550 	if ((id = getPROFILE_ID(sess, obj)) != 0) {
4551 		printf("'%lu'\n", id);
4552 	} else {
4553 		printf("<empty>\n");
4554 	}
4555 }
4556 
4557 
4558 static void
get_token_info(CK_SLOT_ID slot,CK_TOKEN_INFO_PTR info)4559 get_token_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info)
4560 {
4561 	CK_RV		rv;
4562 
4563 	rv = p11->C_GetTokenInfo(slot, info);
4564 	if (rv != CKR_OK)
4565 		p11_fatal("C_GetTokenInfo", rv);
4566 }
4567 
4568 
4569 static CK_ULONG
get_mechanisms(CK_SLOT_ID slot,CK_MECHANISM_TYPE_PTR * pList,CK_FLAGS flags)4570 get_mechanisms(CK_SLOT_ID slot, CK_MECHANISM_TYPE_PTR *pList, CK_FLAGS flags)
4571 {
4572 	CK_ULONG	m, n, ulCount = 0;
4573 	CK_RV		rv;
4574 
4575 	rv = p11->C_GetMechanismList(slot, *pList, &ulCount);
4576 	if (rv != CKR_OK)
4577 		p11_fatal("C_GetMechanismList", rv);
4578 
4579 	*pList = calloc(ulCount, sizeof(**pList));
4580 	if (*pList == NULL)
4581 		util_fatal("calloc failed: %m");
4582 
4583 	rv = p11->C_GetMechanismList(slot, *pList, &ulCount);
4584 	if (rv != CKR_OK)
4585 		p11_fatal("C_GetMechanismList", rv);
4586 
4587 	if (flags != (CK_FLAGS)-1) {
4588 		CK_MECHANISM_TYPE *mechs = *pList;
4589 		CK_MECHANISM_INFO info;
4590 
4591 		for (m = n = 0; n < ulCount; n++) {
4592 			rv = p11->C_GetMechanismInfo(slot, mechs[n], &info);
4593 			if (rv != CKR_OK)
4594 				continue;
4595 			if ((info.flags & flags) == flags)
4596 				mechs[m++] = mechs[n];
4597 		}
4598 		ulCount = m;
4599 	}
4600 
4601 	return ulCount;
4602 }
4603 
4604 #ifdef ENABLE_OPENSSL
BIO_copy_data(BIO * out,long * data_lenp)4605 unsigned char *BIO_copy_data(BIO *out, long *data_lenp) {
4606     unsigned char *data, *tdata;
4607     long data_len;
4608 
4609     data_len = BIO_get_mem_data(out, &tdata);
4610     data = malloc(data_len+1);
4611     if (data) {
4612         memcpy(data, tdata, data_len);
4613 	data[data_len]='\0';  // Make sure it's \0 terminated, in case used as string
4614 	if (data_lenp) {
4615 	    *data_lenp = data_len;
4616 	}
4617     } else {
4618         util_fatal("malloc failed");
4619     }
4620     return data;
4621 }
4622 #endif
4623 
4624 /*
4625  * Read object CKA_VALUE attribute's value.
4626  */
read_object(CK_SESSION_HANDLE session)4627 static int read_object(CK_SESSION_HANDLE session)
4628 {
4629 	CK_RV rv;
4630 	CK_ATTRIBUTE attrs[20];
4631 	CK_OBJECT_CLASS clazz = opt_object_class;
4632 #ifdef ENABLE_OPENSSL
4633 	CK_KEY_TYPE type = CKK_RSA;
4634 #endif
4635 	CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
4636 	int nn_attrs = 0;
4637 	unsigned char *value = NULL, *oid_buf = NULL;
4638 	CK_ULONG len = 0;
4639 	FILE *out;
4640 	struct sc_object_id oid;
4641 	unsigned char subject[0x400], issuer[0x400];
4642 
4643 	if (opt_object_class_str != NULL)   {
4644 		FILL_ATTR(attrs[nn_attrs], CKA_CLASS,
4645 				 &clazz, sizeof(clazz));
4646 		nn_attrs++;
4647 	}
4648 
4649 	if (opt_object_id_len != 0)  {
4650 		FILL_ATTR(attrs[nn_attrs], CKA_ID,
4651 				opt_object_id, opt_object_id_len);
4652 		nn_attrs++;
4653 	}
4654 
4655 	if (opt_object_label != NULL)   {
4656 		FILL_ATTR(attrs[nn_attrs], CKA_LABEL,
4657 				opt_object_label, strlen(opt_object_label));
4658 		nn_attrs++;
4659 	}
4660 
4661 	if (opt_application_label != NULL)   {
4662 		FILL_ATTR(attrs[nn_attrs], CKA_APPLICATION,
4663 				opt_application_label, strlen(opt_application_label));
4664 		nn_attrs++;
4665 	}
4666 
4667 	if (opt_application_id != NULL)   {
4668 		size_t oid_buf_len;
4669 
4670 		if (sc_format_oid(&oid, opt_application_id))
4671 			util_fatal("Invalid OID \"%s\"", opt_application_id);
4672 
4673 		if (sc_asn1_encode_object_id(&oid_buf, &oid_buf_len, &oid))
4674 			util_fatal("Cannot encode OID \"%s\"", opt_application_id);
4675 
4676 		FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID, oid_buf, oid_buf_len);
4677 		nn_attrs++;
4678 	}
4679 
4680 	if (opt_issuer != NULL)   {
4681 		size_t sz = sizeof(issuer);
4682 
4683 		if (sc_hex_to_bin(opt_issuer, issuer, &sz))
4684 			util_fatal("Invalid 'issuer' hexadecimal value");
4685 		FILL_ATTR(attrs[nn_attrs], CKA_ISSUER, issuer,  sz);
4686 		nn_attrs++;
4687 	}
4688 
4689 	if (opt_subject != NULL)   {
4690 		size_t sz = sizeof(subject);
4691 
4692 		if (sc_hex_to_bin(opt_subject, subject, &sz))
4693 			util_fatal("Invalid 'subject' hexadecimal value");
4694 		FILL_ATTR(attrs[nn_attrs], CKA_SUBJECT, subject,  sz);
4695 		nn_attrs++;
4696 	}
4697 
4698 	rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, 0);
4699 	if (rv != CKR_OK)
4700 		p11_fatal("find_object_with_attributes()", rv);
4701 	else if (obj==CK_INVALID_HANDLE)
4702 		util_fatal("object not found");
4703 
4704 /* TODO: -DEE should look at object class, and get appropriate values
4705  * based on the object, and other attributes. For example EC keys do
4706  * not have a VALUE But have a EC_POINT. DvO: done for RSA and EC public keys.
4707  */
4708 	if (clazz == CKO_PRIVATE_KEY) {
4709 		fprintf(stderr, "sorry, reading private keys not (yet) supported\n");
4710 		return 0;
4711 	}
4712 	if (clazz == CKO_PUBLIC_KEY) {
4713 #ifdef ENABLE_OPENSSL
4714 		long derlen;
4715 		BIO *pout = BIO_new(BIO_s_mem());
4716 		if (!pout)
4717 			util_fatal("out of memory");
4718 
4719 		type = getKEY_TYPE(session, obj);
4720 		if (type == CKK_RSA) {
4721 			RSA *rsa;
4722 			BIGNUM *rsa_n = NULL;
4723 			BIGNUM *rsa_e = NULL;
4724 
4725 
4726 			rsa = RSA_new();
4727 			if (rsa == NULL)
4728 				util_fatal("out of memory");
4729 
4730 			if ((value = getMODULUS(session, obj, &len))) {
4731 				if (!(rsa_n = BN_bin2bn(value, len, NULL)))
4732 					util_fatal("cannot parse MODULUS");
4733 				free(value);
4734 			} else
4735 				util_fatal("cannot obtain MODULUS");
4736 
4737 			if ((value = getPUBLIC_EXPONENT(session, obj, &len))) {
4738 				if (!(rsa_e = BN_bin2bn(value, len, NULL)))
4739 					util_fatal("cannot parse PUBLIC_EXPONENT");
4740 				free(value);
4741 			} else
4742 				util_fatal("cannot obtain PUBLIC_EXPONENT");
4743 
4744 			if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1)
4745 				util_fatal("cannot set RSA values");
4746 
4747 			if (!i2d_RSA_PUBKEY_bio(pout, rsa))
4748 				util_fatal("cannot convert RSA public key to DER");
4749 			RSA_free(rsa);
4750 #if !defined(OPENSSL_NO_EC)
4751 		} else if (type == CKK_EC) {
4752 			EC_KEY *ec;
4753 			CK_BYTE *params;
4754 			const unsigned char *a;
4755 			ASN1_OCTET_STRING *os;
4756 			EC_KEY *success = NULL;
4757 
4758 			ec = EC_KEY_new();
4759 			if (ec == NULL)
4760 				util_fatal("out of memory");
4761 
4762 			if ((params = getEC_PARAMS(session, obj, &len))) {
4763 				const unsigned char *a = params;
4764 				if (!d2i_ECParameters(&ec, &a, (long)len))
4765 					util_fatal("cannot parse EC_PARAMS");
4766 				free(params);
4767 			} else
4768 				util_fatal("cannot obtain EC_PARAMS");
4769 
4770 			value = getEC_POINT(session, obj, &len);
4771 			/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */
4772 			a = value;
4773 			os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len);
4774 			if (os) {
4775 				a = os->data;
4776 				success = o2i_ECPublicKey(&ec, &a, os->length);
4777 				ASN1_STRING_free(os);
4778 			}
4779 			if (!success) { /* Workaround for broken PKCS#11 modules */
4780 				a = value;
4781 				success = o2i_ECPublicKey(&ec, &a, len);
4782 			}
4783 			free(value);
4784 			if (!success)
4785 				util_fatal("cannot obtain and parse EC_POINT");
4786 			if (!i2d_EC_PUBKEY_bio(pout, ec))
4787 				util_fatal("cannot convert EC public key to DER");
4788 			EC_KEY_free(ec);
4789 #endif
4790 #ifdef EVP_PKEY_ED25519
4791 		} else if (type == CKK_EC_EDWARDS) {
4792 			EVP_PKEY *key = NULL;
4793 			CK_BYTE *params = NULL;
4794 			const unsigned char *a;
4795 			ASN1_OCTET_STRING *os;
4796 
4797 			if ((params = getEC_PARAMS(session, obj, &len))) {
4798 				ASN1_PRINTABLESTRING *curve = NULL;
4799 				ASN1_OBJECT *obj = NULL;
4800 
4801 				a = params;
4802 				if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) {
4803 					if (strcmp((char *)curve->data, "edwards25519")) {
4804 						util_fatal("Unknown curve name, expected edwards25519, got %s",
4805 							curve->data);
4806 					}
4807 					ASN1_PRINTABLESTRING_free(curve);
4808 				} else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) {
4809 					int nid = OBJ_obj2nid(obj);
4810 					if (nid != NID_ED25519) {
4811 						util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d",
4812 							NID_ED25519, nid);
4813 					}
4814 					ASN1_OBJECT_free(obj);
4815 				} else {
4816 					util_fatal("cannot parse curve name from EC_PARAMS");
4817 				}
4818 				free(params);
4819 			} else {
4820 				util_fatal("cannot obtain EC_PARAMS");
4821 			}
4822 
4823 
4824 			value = getEC_POINT(session, obj, &len);
4825 			/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */
4826 			a = value;
4827 			os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len);
4828 			if (!os) {
4829 				util_fatal("cannot decode EC_POINT");
4830 			}
4831 			if (os->length != 32) {
4832 				util_fatal("Invalid length of EC_POINT value");
4833 			}
4834 			key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
4835 				(const uint8_t *)os->data,
4836 				os->length);
4837 			ASN1_STRING_free(os);
4838 			if (key == NULL) {
4839 				util_fatal("out of memory");
4840 			}
4841 			/* Note, that we write PEM here as there is no "native"
4842 			 * representation of EdDSA public keys to use */
4843 			if (!PEM_write_bio_PUBKEY(pout, key)) {
4844 				util_fatal("cannot convert EdDSA public key to PEM");
4845 			}
4846 
4847 			EVP_PKEY_free(key);
4848 #endif
4849 		}
4850 		else
4851 			util_fatal("Reading public keys of type 0x%lX not (yet) supported", type);
4852 		value = BIO_copy_data(pout, &derlen);
4853 		BIO_free(pout);
4854 		len = derlen;
4855 #else
4856 		util_fatal("No OpenSSL support, cannot read public key");
4857 #endif
4858 	}
4859 	else
4860 		value = getVALUE(session, obj, &len);
4861 	if (value == NULL)
4862 		util_fatal("get CKA_VALUE failed");
4863 
4864 	if (opt_output)   {
4865 		out = fopen(opt_output, "wb");
4866 		if (out==NULL)
4867 			util_fatal("cannot open '%s'", opt_output);
4868 	}
4869 	else
4870 		out = stdout;
4871 
4872 	if (fwrite(value, 1, len, out) != len)
4873 		util_fatal("cannot write to '%s'", opt_output);
4874 	if (opt_output)
4875 		fclose(out);
4876 
4877 	free(value);
4878 	if (oid_buf)
4879 		free(oid_buf);
4880 	return 1;
4881 }
4882 
4883 /*
4884  * Delete object.
4885  */
delete_object(CK_SESSION_HANDLE session)4886 static int delete_object(CK_SESSION_HANDLE session)
4887 {
4888 	CK_RV rv;
4889 	CK_ATTRIBUTE attrs[20];
4890 	CK_OBJECT_CLASS clazz = opt_object_class;
4891 	CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
4892 	int nn_attrs = 0;
4893 	struct sc_object_id oid;
4894 	unsigned char *oid_buf = NULL;
4895 
4896 	if (opt_object_class_str != NULL)   {
4897 		FILL_ATTR(attrs[nn_attrs], CKA_CLASS,
4898 				 &clazz, sizeof(clazz));
4899 		nn_attrs++;
4900 	}
4901 
4902 	if (opt_object_id_len != 0)  {
4903 		FILL_ATTR(attrs[nn_attrs], CKA_ID,
4904 				opt_object_id, opt_object_id_len);
4905 		nn_attrs++;
4906 	}
4907 
4908 	if (opt_object_label != NULL)   {
4909 		FILL_ATTR(attrs[nn_attrs], CKA_LABEL,
4910 				opt_object_label, strlen(opt_object_label));
4911 		nn_attrs++;
4912 	}
4913 
4914 	if (opt_application_label != NULL)   {
4915 		FILL_ATTR(attrs[nn_attrs], CKA_APPLICATION,
4916 				opt_application_label, strlen(opt_application_label));
4917 		nn_attrs++;
4918 	}
4919 
4920 	if (opt_application_id != NULL)   {
4921 		size_t oid_buf_len;
4922 
4923 		if (sc_format_oid(&oid, opt_application_id))
4924 			util_fatal("Invalid OID '%s'", opt_application_id);
4925 
4926 		if (sc_asn1_encode_object_id(&oid_buf, &oid_buf_len, &oid))
4927 			util_fatal("Cannot encode OID \"%s\"", opt_application_id);
4928 
4929 		FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID, oid_buf, oid_buf_len);
4930 		nn_attrs++;
4931 	}
4932 
4933 	rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, opt_object_index);
4934 	if (rv != CKR_OK)
4935 		p11_fatal("find_object_with_attributes()", rv);
4936 	else if (obj==CK_INVALID_HANDLE)
4937 		util_fatal("object not found");
4938 	rv = p11->C_DestroyObject(session, obj);
4939 	if (rv != CKR_OK)
4940 		p11_fatal("C_DestroyObject()", rv);
4941 
4942 	if (oid_buf)
4943 		free(oid_buf);
4944 
4945 	return 1;
4946 }
4947 
get_private_key_length(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE prkey)4948 static CK_ULONG	get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey)
4949 {
4950 	unsigned char  *id;
4951 	CK_ULONG        idLen;
4952 	CK_OBJECT_HANDLE pubkey;
4953 
4954 	id = NULL;
4955 	id = getID(sess, prkey, &idLen);
4956 	if (id == NULL) {
4957 		fprintf(stderr, "private key has no ID, can't lookup the corresponding pubkey\n");
4958 		return 0;
4959 	}
4960 
4961 	if (!find_object(sess, CKO_PUBLIC_KEY, &pubkey, id, idLen, 0)) {
4962 		free(id);
4963 		fprintf(stderr, "couldn't find the corresponding pubkey\n");
4964 		return 0;
4965 	}
4966 	free(id);
4967 
4968 	return getMODULUS_BITS(sess, pubkey);
4969 }
4970 
test_digest(CK_SESSION_HANDLE session)4971 static int test_digest(CK_SESSION_HANDLE session)
4972 {
4973 	int             errors = 0;
4974 	CK_RV           rv;
4975 	CK_MECHANISM    ck_mech = { CKM_MD5, NULL, 0 };
4976 	CK_ULONG        i, j;
4977 	unsigned char   data[100];
4978 	unsigned char   hash1[64], hash2[64];
4979 	CK_ULONG        hashLen1, hashLen2;
4980 	CK_MECHANISM_TYPE firstMechType;
4981 	CK_SESSION_INFO sessionInfo;
4982 
4983 	CK_MECHANISM_TYPE mechTypes[] = {
4984 		CKM_MD5,
4985 		CKM_SHA_1,
4986 		CKM_RIPEMD160,
4987 		0xffffff
4988 	};
4989 	unsigned char  *digests[] = {
4990 		(unsigned char *) "\x7a\x08\xb0\x7e\x84\x64\x17\x03\xe5\xf2\xc8\x36\xaa\x59\xa1\x70",
4991 		(unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",
4992 		(unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd"
4993 	};
4994 	CK_ULONG        digestLens[] = {
4995 		16,
4996 		20,
4997 		20
4998 	};
4999 
5000 	rv = p11->C_GetSessionInfo(session, &sessionInfo);
5001 	if (rv != CKR_OK)
5002 		p11_fatal("C_OpenSession", rv);
5003 
5004 	if (!find_mechanism(sessionInfo.slotID, CKF_DIGEST, NULL, 0, &firstMechType)) {
5005 		fprintf(stderr, "Digests: not implemented\n");
5006 		return errors;
5007 	}
5008 	else    {
5009 		printf("Digests:\n");
5010 	}
5011 
5012 	/* 1st test */
5013 	pseudo_randomize(data, sizeof(data));
5014 
5015 	ck_mech.mechanism = firstMechType;
5016 	rv = p11->C_DigestInit(session, &ck_mech);
5017 	if (rv != CKR_OK)
5018 		p11_fatal("C_DigestInit", rv);
5019 
5020 	rv = p11->C_DigestUpdate(session, data, 5);
5021 	if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
5022 		printf("  Note: C_DigestUpdate(), DigestFinal() not supported\n");
5023 		/* finish the digest operation */
5024 		hashLen2 = sizeof(hash2);
5025 		rv = p11->C_Digest(session, data, sizeof(data), hash2,
5026 			&hashLen2);
5027 		if (rv != CKR_OK)
5028 			p11_fatal("C_Digest", rv);
5029 	} else {
5030 		if (rv != CKR_OK)
5031 			p11_fatal("C_DigestUpdate", rv);
5032 
5033 		rv = p11->C_DigestUpdate(session, data + 5, 50);
5034 		if (rv != CKR_OK)
5035 			p11_fatal("C_DigestUpdate", rv);
5036 
5037 		rv = p11->C_DigestUpdate(session, data + 55,
5038 			sizeof(data) - 55);
5039 		if (rv != CKR_OK)
5040 			p11_fatal("C_DigestUpdate", rv);
5041 
5042 		hashLen1 = sizeof(hash1);
5043 		rv = p11->C_DigestFinal(session, hash1, &hashLen1);
5044 		if (rv != CKR_OK)
5045 			p11_fatal("C_DigestFinal", rv);
5046 
5047 		rv = p11->C_DigestInit(session, &ck_mech);
5048 		if (rv != CKR_OK)
5049 			p11_fatal("C_DigestInit", rv);
5050 
5051 		hashLen2 = sizeof(hash2);
5052 		rv = p11->C_Digest(session, data, sizeof(data), hash2,
5053 			&hashLen2);
5054 		if (rv != CKR_OK)
5055 			p11_fatal("C_Digest", rv);
5056 
5057 		if (hashLen1 != hashLen2) {
5058 			errors++;
5059 			printf("  ERR: digest lengths returned by C_DigestFinal() different from C_Digest()\n");
5060 		} else if (memcmp(hash1, hash2, hashLen1) != 0) {
5061 			errors++;
5062 			printf("  ERR: digests returned by C_DigestFinal() different from C_Digest()\n");
5063 		} else
5064 			printf("  all 4 digest functions seem to work\n");
5065 	}
5066 
5067 	/* 2nd test */
5068 
5069 	/* input = "01234567890123456...456789" */
5070 	for (i = 0; i < 10; i++)
5071 		for (j = 0; j < 10; j++)
5072 			data[10 * i + j] = (unsigned char) (0x30 + j);
5073 
5074 
5075 	for (i = 0; mechTypes[i] != 0xffffff; i++) {
5076 		ck_mech.mechanism = mechTypes[i];
5077 
5078 		rv = p11->C_DigestInit(session, &ck_mech);
5079 		if (rv == CKR_MECHANISM_INVALID)
5080 			continue;	/* mechanism not implemented, don't test */
5081 		if (rv != CKR_OK)
5082 			p11_fatal("C_DigestInit", rv);
5083 
5084 		printf("  %s: ", p11_mechanism_to_name(mechTypes[i]));
5085 
5086 		hashLen1 = sizeof(hash1);
5087 		rv = p11->C_Digest(session, data, sizeof(data), hash1,
5088 			&hashLen1);
5089 		if (rv != CKR_OK)
5090 			p11_fatal("C_Digest", rv);
5091 
5092 		if (hashLen1 != digestLens[i]) {
5093 			errors++;
5094 			printf("ERR: wrong digest length: %ld instead of %ld\n",
5095 					hashLen1, digestLens[i]);
5096 		} else if (memcmp(hash1, digests[i], hashLen1) != 0) {
5097 			errors++;
5098 			printf("ERR: wrong digest value\n");
5099 		} else
5100 			printf("OK\n");
5101 	}
5102 
5103 	/* 3rd test */
5104 
5105 	ck_mech.mechanism = firstMechType;
5106 	rv = p11->C_DigestInit(session, &ck_mech);
5107 	if (rv != CKR_OK)
5108 		p11_fatal("C_DigestInit", rv);
5109 
5110 	hashLen2 = 1;		/* too short */
5111 	rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2);
5112 	if (rv != CKR_BUFFER_TOO_SMALL) {
5113 		errors++;
5114 		printf("  ERR: C_Digest() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5115 	}
5116 	/* output buffer = NULL */
5117 	rv = p11->C_Digest(session, data, sizeof(data), NULL, &hashLen2);
5118 	if (rv != CKR_OK) {
5119 		errors++;
5120 		printf("  ERR: C_Digest() didn't return CKR_OK for a NULL output buffer, but %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5121 	}
5122 
5123 	rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2);
5124 	if (rv == CKR_OPERATION_NOT_INITIALIZED) {
5125 		printf("  ERR: digest operation ended prematurely\n");
5126 		errors++;
5127 	} else if (rv != CKR_OK)
5128 		p11_fatal("C_Sign", rv);
5129 
5130 	return errors;
5131 }
5132 
5133 #ifdef ENABLE_OPENSSL
get_public_key(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE privKeyObject)5134 static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject)
5135 {
5136 	CK_BYTE         *id, *mod, *exp;
5137 	CK_ULONG         idLen = 0, modLen = 0, expLen = 0;
5138 	CK_OBJECT_HANDLE pubkeyObject;
5139 	unsigned char  *pubkey;
5140 	const unsigned char *pubkey_c;
5141 	CK_ULONG        pubkeyLen;
5142 	EVP_PKEY       *pkey;
5143 	RSA            *rsa;
5144 	BIGNUM *rsa_n, *rsa_e;
5145 
5146 	id = NULL;
5147 	id = getID(session, privKeyObject, &idLen);
5148 	if (id == NULL) {
5149 		fprintf(stderr, "private key has no ID, can't lookup the corresponding pubkey for verification\n");
5150 		return NULL;
5151 	}
5152 
5153 	if (!find_object(session, CKO_PUBLIC_KEY, &pubkeyObject, id, idLen, 0)) {
5154 		free(id);
5155 		fprintf(stderr, "couldn't find the corresponding pubkey for validation\n");
5156 		return NULL;
5157 	}
5158 	free(id);
5159 
5160 	switch(getKEY_TYPE(session, pubkeyObject)) {
5161 		case CKK_RSA:
5162 			pkey = EVP_PKEY_new();
5163 			rsa = RSA_new();
5164 			mod = getMODULUS(session, pubkeyObject, &modLen);
5165 			exp = getPUBLIC_EXPONENT(session, pubkeyObject, &expLen);
5166 			if ( !pkey || !rsa || !mod || !exp) {
5167 				fprintf(stderr, "public key not extractable\n");
5168 				if (pkey)
5169 					EVP_PKEY_free(pkey);
5170 				if (rsa)
5171 					RSA_free(rsa);
5172 				if (mod)
5173 					free(mod);
5174 				if (exp)
5175 					free(exp);
5176 				return NULL;
5177 			}
5178 			rsa_n = BN_bin2bn(mod, modLen, NULL);
5179 			rsa_e =	BN_bin2bn(exp, expLen, NULL);
5180 			if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1)
5181 			    return NULL;
5182 
5183 			EVP_PKEY_assign_RSA(pkey, rsa);
5184 			free(mod);
5185 			free(exp);
5186 			return pkey;
5187 		case CKK_DSA:
5188 		case CKK_ECDSA:
5189 		case CKK_GOSTR3410:
5190 			break;
5191 		default:
5192 			fprintf(stderr, "public key of unsupported type\n");
5193 			return NULL;
5194 	}
5195 
5196 	pubkey = getVALUE(session, pubkeyObject, &pubkeyLen);
5197 	if (pubkey == NULL) {
5198 		fprintf(stderr, "couldn't get the pubkey VALUE attribute, no validation done\n");
5199 		return NULL;
5200 	}
5201 
5202 	pubkey_c = pubkey;
5203 	pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey_c, pubkeyLen);
5204 	free(pubkey);
5205 
5206 	if (pkey == NULL) {
5207 		fprintf(stderr, "couldn't parse pubkey, no verification done\n");
5208 		return NULL;
5209 	}
5210 
5211 	return pkey;
5212 }
5213 #endif
5214 
sign_verify_openssl(CK_SESSION_HANDLE session,CK_MECHANISM * ck_mech,CK_OBJECT_HANDLE privKeyObject,unsigned char * data,CK_ULONG dataLen,unsigned char * verifyData,CK_ULONG verifyDataLen,CK_ULONG modLenBytes,int evp_md_index)5215 static int sign_verify_openssl(CK_SESSION_HANDLE session,
5216 		CK_MECHANISM *ck_mech, CK_OBJECT_HANDLE privKeyObject,
5217 		unsigned char *data, CK_ULONG dataLen,
5218 		unsigned char *verifyData, CK_ULONG verifyDataLen,
5219 		CK_ULONG modLenBytes, int evp_md_index)
5220 {
5221 	int 		errors = 0;
5222 	CK_RV           rv;
5223 	unsigned char   sig1[1024];
5224 	CK_ULONG        sigLen1;
5225 
5226 #ifdef ENABLE_OPENSSL
5227 	int             err;
5228 	EVP_PKEY       *pkey;
5229 	EVP_MD_CTX      *md_ctx;
5230 
5231 	const EVP_MD         *evp_mds[] = {
5232 		EVP_sha1(),
5233 		EVP_sha1(),
5234 		EVP_sha1(),
5235 		EVP_md5(),
5236 #ifndef OPENSSL_NO_RIPEMD
5237 		EVP_ripemd160(),
5238 #endif
5239 		EVP_sha256(),
5240 	};
5241 #endif
5242 
5243 	rv = p11->C_SignInit(session, ck_mech, privKeyObject);
5244 	/* mechanism not implemented, don't test */
5245 	if (rv == CKR_MECHANISM_INVALID)
5246 		return errors;
5247 	if (rv != CKR_OK)
5248 		p11_fatal("C_SignInit", rv);
5249 	if (getALWAYS_AUTHENTICATE(session, privKeyObject))
5250 		login(session,CKU_CONTEXT_SPECIFIC);
5251 	printf("    %s: ", p11_mechanism_to_name(ck_mech->mechanism));
5252 
5253 	sigLen1 = sizeof(sig1);
5254 	rv = p11->C_Sign(session, data, dataLen, sig1,
5255 		&sigLen1);
5256 	if (rv != CKR_OK)
5257 		p11_fatal("C_Sign", rv);
5258 
5259 	if (sigLen1 != modLenBytes) {
5260 		errors++;
5261 		printf("  ERR: wrong signature length: %u instead of %u\n",
5262 				(unsigned int) sigLen1,
5263 				(unsigned int) modLenBytes);
5264 	}
5265 #ifndef ENABLE_OPENSSL
5266 	fprintf(stderr, "unable to verify signature (compile with ENABLE_OPENSSL)\n");
5267 #else
5268 
5269 	if (!(pkey = get_public_key(session, privKeyObject)))
5270 		return errors;
5271 
5272 	md_ctx = EVP_MD_CTX_create();
5273 	if (!md_ctx)
5274 		err = -1;
5275 	else {
5276 		if (EVP_VerifyInit(md_ctx, evp_mds[evp_md_index])
5277 				&& EVP_VerifyUpdate(md_ctx, verifyData, verifyDataLen)) {
5278 			err = EVP_VerifyFinal(md_ctx, sig1, sigLen1, pkey);
5279 		} else {
5280 			err = -1;
5281 		}
5282 		EVP_MD_CTX_destroy(md_ctx);
5283 		EVP_PKEY_free(pkey);
5284 	}
5285 	if (err == 0) {
5286 		printf("ERR: verification failed\n");
5287 		errors++;
5288 	} else if (err != 1) {
5289 		printf("openssl error during verification: 0x%0x (%d)\n", err, err);
5290 	} else
5291 		printf("OK\n");
5292 
5293 	/* free(cert); */
5294 #endif
5295 
5296 	return errors;
5297 }
5298 
5299 /*
5300  * Test signature functions
5301  */
test_signature(CK_SESSION_HANDLE sess)5302 static int test_signature(CK_SESSION_HANDLE sess)
5303 {
5304 	int             errors = 0;
5305 	CK_RV           rv;
5306 	CK_OBJECT_HANDLE pubKeyObject, privKeyObject;
5307 	CK_MECHANISM    ck_mech = { CKM_MD5, NULL, 0 };
5308 	CK_MECHANISM_TYPE firstMechType;
5309 	CK_SESSION_INFO sessionInfo;
5310 	CK_ULONG        i, j;
5311 	unsigned char   data[512]; /* FIXME: Will not work for keys above 4096 bits */
5312 	CK_ULONG        modLenBytes = 0;
5313 	CK_ULONG        dataLen;
5314 	unsigned char   sig1[1024], sig2[1024];
5315 	CK_ULONG        sigLen1, sigLen2;
5316 	unsigned char   verifyData[100];
5317 	char 		*label;
5318 
5319 	CK_MECHANISM_TYPE mechTypes[] = {
5320 		CKM_RSA_X_509,
5321 		CKM_RSA_PKCS,
5322 		CKM_SHA1_RSA_PKCS,
5323 		CKM_MD5_RSA_PKCS,
5324 #ifndef OPENSSL_NO_RIPEMD
5325 		CKM_RIPEMD160_RSA_PKCS,
5326 #endif
5327 		CKM_SHA256_RSA_PKCS,
5328 		0xffffff
5329 	};
5330 	size_t mechTypes_num = sizeof(mechTypes)/sizeof(CK_MECHANISM_TYPE);
5331 	unsigned char  *datas[] = {
5332 		/* PCKS1_wrap(SHA1_encode(SHA-1(verifyData))),
5333 		 * is done further on
5334 		 */
5335 		NULL,
5336 
5337 		/* SHA1_encode(SHA-1(verifyData)) */
5338 		(unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",
5339 
5340 		verifyData,
5341 		verifyData,
5342 		verifyData,
5343 		verifyData,
5344 	};
5345 	CK_ULONG        dataLens[] = {
5346 		0,		/* should be modulus length, is done further on */
5347 		35,
5348 		sizeof(verifyData),
5349 		sizeof(verifyData),
5350 		sizeof(verifyData),
5351 		sizeof(verifyData),
5352 	};
5353 
5354 	rv = p11->C_GetSessionInfo(sess, &sessionInfo);
5355 	if (rv != CKR_OK)
5356 		p11_fatal("C_OpenSession", rv);
5357 	if (!(sessionInfo.state & CKS_RW_USER_FUNCTIONS)) {
5358 		printf("Signature: not a R/W session, skipping signature tests\n");
5359 		return errors;
5360 	}
5361 
5362 	if (!find_mechanism(sessionInfo.slotID, CKF_SIGN|opt_allow_sw, mechTypes, mechTypes_num, &firstMechType)) {
5363 		printf("Signatures: not implemented\n");
5364 		return errors;
5365 	}
5366 
5367 	printf("Signatures (currently only for RSA)\n");
5368 	for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) {
5369 		printf("  testing key %ld ", j);
5370 		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {
5371 			printf("(%s) ", label);
5372 			free(label);
5373 		}
5374 		if (getKEY_TYPE(sess, privKeyObject) != CKK_RSA) {
5375 			printf(" -- non-RSA, skipping\n");
5376 			continue;
5377 		}
5378 
5379 		if (!getSIGN(sess, privKeyObject)) {
5380 			printf(" -- can't be used for signature, skipping\n");
5381 			continue;
5382 		}
5383 
5384 		modLenBytes = (get_private_key_length(sess, privKeyObject) + 7) / 8;
5385 		if(!modLenBytes) {
5386 			printf(" -- can't be used for signature, skipping: can't obtain modulus\n");
5387 			continue;
5388 		}
5389 		printf("\n");
5390 		break;
5391 	}
5392 	if (privKeyObject == CK_INVALID_HANDLE) {
5393 		fprintf(stderr, "Signatures: no private key found in this slot\n");
5394 		return 0;
5395 	}
5396 
5397 	/* 1st test */
5398 
5399 	/* assume --login has already authenticated the key */
5400 	switch (firstMechType) {
5401 	case CKM_RSA_PKCS:
5402 		dataLen = 35;
5403 		memcpy(data, datas[1], dataLen);
5404 		break;
5405 	case CKM_RSA_X_509:
5406 		dataLen = modLenBytes;
5407 		pseudo_randomize(data, dataLen);
5408 		break;
5409 	default:
5410 		dataLen = sizeof(data);	/* let's hope it's OK */
5411 		pseudo_randomize(data, dataLen);
5412 		break;
5413 	}
5414 
5415 	if (firstMechType == CKM_RSA_X_509) {
5416 		/* make sure our data is smaller than the modulus - 11 */
5417 		memset(data, 0, 11); /* in effect is zero padding */
5418 	}
5419 
5420 	ck_mech.mechanism = firstMechType;
5421 	rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);
5422 	/* mechanism not implemented, don't test */
5423 	if (rv == CKR_MECHANISM_INVALID)
5424 		return errors;
5425 	if (rv != CKR_OK)
5426 		p11_fatal("C_SignInit", rv);
5427 	if (getALWAYS_AUTHENTICATE(sess, privKeyObject))
5428 		login(sess,CKU_CONTEXT_SPECIFIC);
5429 
5430 	rv = p11->C_SignUpdate(sess, data, 5);
5431 	if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
5432 		p11_warn("C_SignUpdate", rv);
5433 	} else if (rv != CKR_OK) {
5434 		p11_perror("C_SignUpdate", rv);
5435 		errors++;
5436 	} else {
5437 		if (rv != CKR_OK)
5438 			p11_fatal("C_SignUpdate", rv);
5439 
5440 		rv = p11->C_SignUpdate(sess, data + 5, 10);
5441 		if (rv != CKR_OK)
5442 			p11_fatal("C_SignUpdate", rv);
5443 
5444 		rv = p11->C_SignUpdate(sess, data + 15, dataLen - 15);
5445 		if (rv != CKR_OK)
5446 			p11_fatal("C_SignUpdate", rv);
5447 
5448 		sigLen1 = sizeof(sig1);
5449 		rv = p11->C_SignFinal(sess, sig1, &sigLen1);
5450 		if (rv != CKR_OK)
5451 			p11_fatal("C_SignFinal", rv);
5452 
5453 		rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);
5454 		if (rv != CKR_OK)
5455 			p11_fatal("C_SignInit", rv);
5456 		if (getALWAYS_AUTHENTICATE(sess, privKeyObject))
5457 			login(sess,CKU_CONTEXT_SPECIFIC);
5458 
5459 		sigLen2 = sizeof(sig2);
5460 		rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);
5461 		if (rv != CKR_OK)
5462 			p11_fatal("C_Sign", rv);
5463 
5464 		if (sigLen1 != sigLen2) {
5465 			errors++;
5466 			printf("  ERR: signature lengths returned by C_SignFinal() different from C_Sign()\n");
5467 		} else if (memcmp(sig1, sig2, sigLen1) != 0) {
5468 			errors++;
5469 			printf("  ERR: signatures returned by C_SignFinal() different from C_Sign()\n");
5470 		} else
5471 			printf("  all 4 signature functions seem to work\n");
5472 	}
5473 
5474 	/* 2nd test */
5475 
5476 	ck_mech.mechanism = firstMechType;
5477 	rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);
5478 	if (rv != CKR_OK)
5479 		p11_fatal("C_SignInit", rv);
5480 
5481 	sigLen2 = 1;		/* too short */
5482 	rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);
5483 	if (rv != CKR_BUFFER_TOO_SMALL) {
5484 		errors++;
5485 		printf("  ERR: C_Sign() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5486 	}
5487 
5488 	/* output buf = NULL */
5489 	rv = p11->C_Sign(sess, data, dataLen, NULL, &sigLen2);
5490 	if (rv != CKR_OK) {
5491 	   errors++;
5492 	   printf("  ERR: C_Sign() didn't return CKR_OK for a NULL output buf, but %s (0x%0x)\n",
5493 	   CKR2Str(rv), (int) rv);
5494 	}
5495 	if (getALWAYS_AUTHENTICATE(sess, privKeyObject))
5496 		login(sess,CKU_CONTEXT_SPECIFIC);
5497 
5498 	rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);
5499 	if (rv == CKR_OPERATION_NOT_INITIALIZED) {
5500 		printf("  ERR: signature operation ended prematurely\n");
5501 		errors++;
5502 	} else if (rv != CKR_OK)
5503 		p11_fatal("C_Sign", rv);
5504 
5505 	/* 3rd test */
5506 
5507 	/* input = "01234567890123456...456789" */
5508 	for (i = 0; i < 10; i++)
5509 		for (j = 0; j < 10; j++)
5510 			verifyData[10 * i + j] = (unsigned char) (0x30 + j);
5511 
5512 	/* Fill in data[0] and dataLens[0] */
5513 	dataLen = modLenBytes;
5514 	data[0] = 0x00;
5515 	data[1] = 0x01;
5516 	memset(data + 2, 0xFF, dataLen - 3 - dataLens[1]);
5517 	if (dataLen >= 36)
5518 		data[dataLen - 36] = 0x00;
5519 	memcpy(data + (dataLen - dataLens[1]), datas[1], dataLens[1]);
5520 	datas[0] = data;
5521 	dataLens[0] = dataLen;
5522 
5523 	printf("  testing signature mechanisms:\n");
5524 	for (i = 0; mechTypes[i] != 0xffffff; i++) {
5525 		ck_mech.mechanism = mechTypes[i];
5526 		errors += sign_verify_openssl(sess, &ck_mech, privKeyObject,
5527 			datas[i], dataLens[i], verifyData, sizeof(verifyData),
5528 			modLenBytes, i);
5529 	}
5530 
5531 	/* 4th test: the other signature keys */
5532 
5533 	for (i = 0; mechTypes[i] != 0xffffff; i++)
5534 		if (mechTypes[i] == firstMechType)
5535 			break;
5536 	ck_mech.mechanism = mechTypes[i];
5537 	j = 1;  /* j-th signature key */
5538 	while (find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j++) != 0) {
5539 		unsigned char   *id;
5540 		CK_ULONG        idLen;
5541 		CK_ULONG	modLenBits;
5542 
5543 		printf("  testing key %d", (int) (j-1));
5544 		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {
5545 			printf(" (%s)", label);
5546 			free(label);
5547 		}
5548 		if ((int) (j-1) != 0)
5549 			printf(" with 1 mechanism");
5550 
5551 		if (getKEY_TYPE(sess, privKeyObject) != CKK_RSA) {
5552 			printf(" -- non-RSA, skipping\n");
5553 			continue;
5554 		}
5555 		if (!getSIGN(sess, privKeyObject)) {
5556 			printf(" -- can't be used to sign/verify, skipping\n");
5557 			continue;
5558 		}
5559 		if ((id = getID(sess, privKeyObject, &idLen)) != NULL) {
5560 			int r;
5561 
5562 			r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, idLen, 0);
5563 			free(id);
5564 			if (r == 0) {
5565 				printf(" -- can't find corresponding public key, skipping\n");
5566 				continue;
5567 			}
5568 		}
5569 		else {
5570 			printf(" -- can't get the ID for looking up the public key, skipping\n");
5571 			continue;
5572 		}
5573 
5574 		modLenBits = get_private_key_length(sess, privKeyObject);
5575 		modLenBytes = (modLenBits + 7) / 8;
5576 		if (!modLenBytes)   {
5577 			printf(" -- can't be used to sign/verify, skipping: can't obtain modulus\n");
5578 			continue;
5579 		}
5580 		printf("\n");
5581 
5582 		/* Fill in data[0] and dataLens[0] */
5583 		dataLen = modLenBytes;
5584 		data[0] = 0x00;
5585 		data[1] = 0x01;
5586 		memset(data + 2, 0xFF, dataLen - 3 - dataLens[1]);
5587 		data[dataLen - 36] = 0x00;
5588 		memcpy(data + (dataLen - dataLens[1]), datas[1], dataLens[1]);
5589 		datas[0] = data;
5590 		dataLens[0] = dataLen;
5591 
5592 		errors += sign_verify_openssl(sess, &ck_mech, privKeyObject,
5593 			datas[i], dataLens[i], verifyData, sizeof(verifyData),
5594 			modLenBytes, i);
5595 	}
5596 
5597 	return errors;
5598 }
5599 
sign_verify(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE priv_key,int key_len,CK_OBJECT_HANDLE pub_key,int one_test)5600 static int sign_verify(CK_SESSION_HANDLE session,
5601 	CK_OBJECT_HANDLE priv_key, int key_len,
5602 	CK_OBJECT_HANDLE pub_key, int one_test)
5603 {
5604 	CK_RV rv;
5605 	CK_MECHANISM_TYPE mech_types[] = {
5606 		CKM_RSA_X_509,
5607 		CKM_RSA_PKCS,
5608 		CKM_SHA1_RSA_PKCS,
5609 		CKM_MD5_RSA_PKCS,
5610 		CKM_RIPEMD160_RSA_PKCS,
5611 		0xffffff
5612 	};
5613 	CK_MECHANISM_TYPE *mech_type;
5614 	unsigned char buf[512] = {0};
5615 	unsigned char *datas[] = {
5616 		buf,
5617 		(unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",
5618 		buf,
5619 		buf,
5620 		buf
5621 	};
5622 	int data_lens[] = {
5623 		key_len,
5624 		35,
5625 		234,
5626 		345,
5627 		456
5628 	};
5629 	unsigned char signat[512];
5630 	CK_ULONG signat_len;
5631 	int j, errors = 0;
5632 
5633 	memcpy(buf, "\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", 11);
5634 
5635 	for (j = 0, mech_type = mech_types; *mech_type != 0xffffff; mech_type++, j++) {
5636 		CK_MECHANISM mech = {*mech_type, NULL, 0};
5637 
5638 		rv = p11->C_SignInit(session, &mech, priv_key);
5639 		if (rv == CKR_MECHANISM_INVALID)
5640 			continue;
5641 		if (rv != CKR_OK) {
5642 			printf("  ERR: C_SignInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5643 			return ++errors;
5644 		}
5645 		if (getALWAYS_AUTHENTICATE(session, priv_key))
5646 			login(session,CKU_CONTEXT_SPECIFIC);
5647 		printf("    %s: ", p11_mechanism_to_name(*mech_type));
5648 
5649 		signat_len = sizeof(signat);
5650 		rv = p11->C_Sign(session, datas[j], data_lens[j], signat, &signat_len);
5651 		if (rv != CKR_OK) {
5652 			printf("  ERR: C_Sign() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5653 			return ++errors;
5654 		}
5655 
5656 		rv = p11->C_VerifyInit(session, &mech, pub_key);
5657 		if (rv != CKR_OK) {
5658 			printf("  ERR: C_VerifyInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5659 			return ++errors;
5660 		}
5661 		rv = p11->C_Verify(session, datas[j], data_lens[j], signat, signat_len);
5662 		if (rv == CKR_SIGNATURE_INVALID) {
5663 			printf("  ERR: verification failed");
5664 			errors++;
5665 		}
5666 		if (rv != CKR_OK) {
5667 			printf("  ERR: C_Verify() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);
5668 			return ++errors;
5669 		}
5670 		else
5671 			printf("OK\n");
5672 
5673 		if (one_test)
5674 			return errors;
5675 	}
5676 
5677 	return errors;
5678 }
5679 
test_verify(CK_SESSION_HANDLE sess)5680 static int test_verify(CK_SESSION_HANDLE sess)
5681 {
5682 	int key_len, i, errors = 0;
5683 	CK_OBJECT_HANDLE priv_key, pub_key;
5684 	CK_MECHANISM_TYPE first_mech_type;
5685 	CK_SESSION_INFO sessionInfo;
5686 	CK_RV rv;
5687 
5688 	rv = p11->C_GetSessionInfo(sess, &sessionInfo);
5689 	if (rv != CKR_OK)
5690 		p11_fatal("C_OpenSession", rv);
5691 	if (!(sessionInfo.state & CKS_RW_USER_FUNCTIONS)) {
5692 		printf("Verify: not a R/W session, skipping verify tests\n");
5693 		return errors;
5694 	}
5695 
5696 	if (!find_mechanism(sessionInfo.slotID, CKF_VERIFY, NULL, 0, &first_mech_type)) {
5697 		printf("Verify: not implemented\n");
5698 		return errors;
5699 	}
5700 
5701 	printf("Verify (currently only for RSA)\n");
5702 
5703 	for (i = 0; find_object(sess, CKO_PRIVATE_KEY, &priv_key, NULL, 0, i); i++) {
5704 		char *label;
5705 		unsigned char *id;
5706 		CK_ULONG id_len;
5707 
5708 		printf("  testing key %d", i);
5709 		if ((label = getLABEL(sess, priv_key, NULL)) != NULL) {
5710 			printf(" (%s)", label);
5711 			free(label);
5712 		}
5713 		if (i != 0)
5714 			printf(" with 1 mechanism");
5715 		if (getKEY_TYPE(sess, priv_key) != CKK_RSA) {
5716 			printf(" -- non-RSA, skipping\n");
5717 			continue;
5718 		}
5719 
5720 		if (!getSIGN(sess, priv_key)) {
5721 			printf(" -- can't be used to sign/verify, skipping\n");
5722 			continue;
5723 		}
5724 		if ((id = getID(sess, priv_key, &id_len)) != NULL) {
5725 			int r;
5726 
5727 			r = find_object(sess, CKO_PUBLIC_KEY, &pub_key, id, id_len, 0);
5728 			free(id);
5729 			if (r == 0) {
5730 				printf(" -- can't find corresponding public key, skipping\n");
5731 				continue;
5732 			}
5733 		}
5734 		else {
5735 			printf(" -- can't get the ID for looking up the public key, skipping\n");
5736 			continue;
5737 		}
5738 
5739 		key_len = (get_private_key_length(sess, priv_key) + 7) / 8;
5740 		if(!key_len) {
5741 			printf(" -- can't get the modulus length, skipping\n");
5742 			continue;
5743 		}
5744 		printf("\n");
5745 
5746 		errors += sign_verify(sess, priv_key, key_len, pub_key, i != 0);
5747 	}
5748 
5749 	if (i == 0)
5750 		printf("  No private key found for testing\n");
5751 
5752 	return errors;
5753 }
5754 
5755 #if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 22
5756 #else
5757 #ifdef ENABLE_OPENSSL
wrap_unwrap(CK_SESSION_HANDLE session,const EVP_CIPHER * algo,CK_OBJECT_HANDLE privKeyObject)5758 static int wrap_unwrap(CK_SESSION_HANDLE session,
5759 	    const EVP_CIPHER *algo, CK_OBJECT_HANDLE privKeyObject)
5760 {
5761 	CK_OBJECT_HANDLE cipherKeyObject;
5762 	CK_RV           rv;
5763 	EVP_PKEY       *pkey;
5764 	EVP_CIPHER_CTX	* seal_ctx;
5765 	unsigned char	keybuf[512], *key = keybuf;
5766 	int		key_len;
5767 	unsigned char	iv[32], ciphered[1024], cleartext[1024];
5768 	int		ciphered_len, cleartext_len, len;
5769 	CK_MECHANISM	mech;
5770 	CK_ULONG	key_type = CKM_DES_CBC;
5771 	CK_ULONG key_len_ul;
5772 	CK_ATTRIBUTE	key_template = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
5773 
5774 	pkey = get_public_key(session, privKeyObject);
5775 	if (pkey == NULL)
5776 		return 0;
5777 
5778 	printf("    %s: ", OBJ_nid2sn(EVP_CIPHER_nid(algo)));
5779 
5780 	seal_ctx = EVP_CIPHER_CTX_new();
5781 	if (seal_ctx == NULL) {
5782 		printf("Internal error.\n");
5783 		return 1;
5784 	}
5785 
5786 	if (!EVP_SealInit(seal_ctx, algo,
5787 			&key, &key_len,
5788 			iv, &pkey, 1)) {
5789 		fprintf(stderr, "Internal error.\n");
5790 		return 1;
5791 	}
5792 
5793 	/* Encrypt something */
5794 	len = sizeof(ciphered);
5795 	if (!EVP_SealUpdate(seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11)) {
5796 		printf("Internal error.\n");
5797 		return 1;
5798 	}
5799 	ciphered_len = len;
5800 
5801 	len = sizeof(ciphered) - ciphered_len;
5802 	if (!EVP_SealFinal(seal_ctx, ciphered + ciphered_len, &len)) {
5803 		printf("Internal error.\n");
5804 		return 1;
5805 	}
5806 	ciphered_len += len;
5807 
5808 	EVP_PKEY_free(pkey);
5809 
5810 	mech.mechanism = CKM_RSA_PKCS;
5811 	rv = p11->C_UnwrapKey(session, &mech, privKeyObject,
5812 			key, key_len,
5813 			&key_template, 1,
5814 			&cipherKeyObject);
5815 
5816 	/* mechanism not implemented, don't test */
5817 	if (rv == CKR_MECHANISM_INVALID) {
5818 		printf("Wrap mechanism not supported, skipped\n");
5819 		return 0;
5820 	}
5821 	if (rv != CKR_OK) {
5822 		p11_perror("C_UnwrapKey", rv);
5823 		return 1;
5824 	}
5825 
5826 	/* Try to decrypt */
5827 	key = getVALUE(session, cipherKeyObject, &key_len_ul);
5828 	key_len = key_len_ul;
5829 	if (key == NULL) {
5830 		fprintf(stderr, "Could not get unwrapped key\n");
5831 		return 1;
5832 	}
5833 	if (key_len != EVP_CIPHER_key_length(algo)) {
5834 		fprintf(stderr, "Key length mismatch (%d != %d)\n",
5835 				key_len, EVP_CIPHER_key_length(algo));
5836 		return 1;
5837 	}
5838 
5839 	if (!EVP_DecryptInit(seal_ctx, algo, key, iv)) {
5840 		printf("Internal error.\n");
5841 		return 1;
5842 	}
5843 
5844 	len = sizeof(cleartext);
5845 	if (!EVP_DecryptUpdate(seal_ctx, cleartext, &len, ciphered, ciphered_len)) {
5846 		printf("Internal error.\n");
5847 		return 1;
5848 	}
5849 
5850 	cleartext_len = len;
5851 	len = sizeof(cleartext) - len;
5852 	if (!EVP_DecryptFinal(seal_ctx, cleartext + cleartext_len, &len)) {
5853 		printf("Internal error.\n");
5854 		return 1;
5855 	}
5856 	cleartext_len += len;
5857 
5858 	if (cleartext_len != 11
5859 	 || memcmp(cleartext, "hello world", 11)) {
5860 		printf("resulting cleartext doesn't match input\n");
5861 		return 1;
5862 	}
5863 
5864 	if (seal_ctx)
5865 	    EVP_CIPHER_CTX_free(seal_ctx);
5866 
5867 	printf("OK\n");
5868 	return 0;
5869 }
5870 #endif
5871 #endif
5872 
5873 
5874 /*
5875  * Test unwrap functions
5876  */
test_unwrap(CK_SESSION_HANDLE sess)5877 static int test_unwrap(CK_SESSION_HANDLE sess)
5878 {
5879 #if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 22
5880 	/* temporarily disable test, see https://github.com/OpenSC/OpenSC/issues/1796 */
5881 	return 0;
5882 #else
5883 	int             errors = 0;
5884 	CK_RV           rv;
5885 	CK_OBJECT_HANDLE privKeyObject;
5886 	CK_MECHANISM_TYPE firstMechType;
5887 	CK_SESSION_INFO sessionInfo;
5888 	CK_ULONG        j;
5889 	char 		*label;
5890 
5891 	rv = p11->C_GetSessionInfo(sess, &sessionInfo);
5892 	if (rv != CKR_OK)
5893 		p11_fatal("C_OpenSession", rv);
5894 	if (!(sessionInfo.state & CKS_RW_USER_FUNCTIONS)) {
5895 		printf("Key unwrap: not a R/W session, skipping key unwrap tests\n");
5896 		return errors;
5897 	}
5898 
5899 	if (!find_mechanism(sessionInfo.slotID, CKF_UNWRAP|opt_allow_sw, NULL, 0, &firstMechType)) {
5900 		printf("Unwrap: not implemented\n");
5901 		return errors;
5902 	}
5903 
5904 	printf("Key unwrap (currently only for RSA)\n");
5905 	for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) {
5906 		printf("  testing key %ld ", j);
5907 		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {
5908 			printf("(%s) ", label);
5909 			free(label);
5910 		}
5911 		if (getKEY_TYPE(sess, privKeyObject) != CKK_RSA) {
5912 			printf(" -- non-RSA, skipping\n");
5913 			continue;
5914 		}
5915 		if (!getUNWRAP(sess, privKeyObject)) {
5916 			printf(" -- can't be used to unwrap, skipping\n");
5917 			continue;
5918 		}
5919 		printf("\n");
5920 
5921 #ifndef ENABLE_OPENSSL
5922 		printf("No OpenSSL support, unable to validate C_Unwrap\n");
5923 #else
5924 		errors += wrap_unwrap(sess, EVP_des_cbc(), privKeyObject);
5925 		errors += wrap_unwrap(sess, EVP_des_ede3_cbc(), privKeyObject);
5926 		errors += wrap_unwrap(sess, EVP_bf_cbc(), privKeyObject);
5927 #ifndef OPENSSL_NO_CAST
5928 		errors += wrap_unwrap(sess, EVP_cast5_cfb(), privKeyObject);
5929 #endif
5930 #endif
5931 	}
5932 
5933 	return errors;
5934 #endif
5935 }
5936 
5937 #ifdef ENABLE_OPENSSL
encrypt_decrypt(CK_SESSION_HANDLE session,CK_MECHANISM_TYPE mech_type,CK_OBJECT_HANDLE privKeyObject)5938 static int encrypt_decrypt(CK_SESSION_HANDLE session,
5939 		CK_MECHANISM_TYPE mech_type,
5940 		CK_OBJECT_HANDLE privKeyObject)
5941 {
5942 	EVP_PKEY       *pkey;
5943 	unsigned char	orig_data[512];
5944 	unsigned char	encrypted[512], data[512];
5945 	CK_MECHANISM	mech;
5946 	CK_ULONG	encrypted_len, data_len;
5947 	int             failed;
5948 	CK_RV           rv;
5949 	int             pad;
5950 	CK_MECHANISM_TYPE hash_alg = CKM_SHA256;
5951 	CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256;
5952 	CK_RSA_PKCS_OAEP_PARAMS oaep_params;
5953 
5954 	printf("    %s: ", p11_mechanism_to_name(mech_type));
5955 
5956 	pseudo_randomize(orig_data, sizeof(orig_data));
5957 	orig_data[0] = 0; /* Make sure it is less then modulus */
5958 
5959 	pkey = get_public_key(session, privKeyObject);
5960 	if (pkey == NULL)
5961 		return 0;
5962 
5963 	if (EVP_PKEY_size(pkey) > (int)sizeof(encrypted)) {
5964 		printf("Ciphertext buffer too small\n");
5965 		EVP_PKEY_free(pkey);
5966 		return 0;
5967 	}
5968 	size_t in_len;
5969 	size_t max_in_len;
5970 	CK_ULONG mod_len = (get_private_key_length(session, privKeyObject) + 7) / 8;
5971 	switch (mech_type) {
5972 	case CKM_RSA_PKCS:
5973 		pad = RSA_PKCS1_PADDING;
5974 		/* input length <= mod_len-11 */
5975 		max_in_len = mod_len-11;
5976 		in_len = 10;
5977 		break;
5978 	case CKM_RSA_PKCS_OAEP: {
5979 		if (opt_hash_alg != 0) {
5980 			hash_alg = opt_hash_alg;
5981 		}
5982 		switch (hash_alg) {
5983 		case CKM_SHA_1:
5984 			mgf = CKG_MGF1_SHA1;
5985 			break;
5986 		case CKM_SHA224:
5987 			mgf = CKG_MGF1_SHA224;
5988 			break;
5989 		default:
5990 			printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(hash_alg));
5991 			/* fall through */
5992 		case CKM_SHA256:
5993 			mgf = CKG_MGF1_SHA256;
5994 			break;
5995 		case CKM_SHA384:
5996 			mgf = CKG_MGF1_SHA384;
5997 			break;
5998 		case CKM_SHA512:
5999 			mgf = CKG_MGF1_SHA512;
6000 			break;
6001 		}
6002 		if (opt_mgf != 0) {
6003 			mgf = opt_mgf;
6004 		} else {
6005 			printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(mgf));
6006 		}
6007 
6008 		pad = RSA_PKCS1_OAEP_PADDING;
6009 		size_t len = 2+2*hash_length(hash_alg);
6010 		if (len >= mod_len) {
6011 			printf("Incompatible mechanism and key size\n");
6012 			return 0;
6013 		}
6014 		/* input length <= mod_len-2-2*hlen */
6015 		max_in_len = mod_len-len;
6016 		in_len = 10;
6017 		break;
6018 	}
6019 	case CKM_RSA_X_509:
6020 		pad = RSA_NO_PADDING;
6021 		/* input length equals modulus length */
6022 		max_in_len = mod_len;
6023 		in_len = mod_len;
6024 		break;
6025 	default:
6026 		printf("Unsupported mechanism %s, returning\n", p11_mechanism_to_name(mech_type));
6027 		return 0;
6028 	}
6029 
6030 	if (in_len > sizeof(orig_data)) {
6031 		printf("Input data is too large\n");
6032 		return 0;
6033 	}
6034 	if (in_len > max_in_len) {
6035 		printf("Input data is too large for this key\n");
6036 		return 0;
6037 	}
6038 
6039 	EVP_PKEY_CTX *ctx;
6040 	ctx = EVP_PKEY_CTX_new(pkey, NULL);
6041 	if (!ctx) {
6042 		EVP_PKEY_free(pkey);
6043 		printf("EVP_PKEY_CTX_new failed, returning\n");
6044 		return 0;
6045 	}
6046 	if (EVP_PKEY_encrypt_init(ctx) <= 0) {
6047 		EVP_PKEY_CTX_free(ctx);
6048 		EVP_PKEY_free(pkey);
6049 		printf("EVP_PKEY_encrypt_init failed, returning\n");
6050 		return 0;
6051 	}
6052 	if (EVP_PKEY_CTX_set_rsa_padding(ctx, pad) <= 0) {
6053 		EVP_PKEY_CTX_free(ctx);
6054 		EVP_PKEY_free(pkey);
6055 		printf("set padding failed, returning\n");
6056 		return 0;
6057 	}
6058 	if (mech_type == CKM_RSA_PKCS_OAEP) {
6059 #if defined(EVP_PKEY_CTX_set_rsa_oaep_md) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md)
6060 		const EVP_MD *md;
6061 		switch (hash_alg) {
6062 		case CKM_SHA_1:
6063 			md = EVP_sha1();
6064 			break;
6065 		case CKM_SHA224:
6066 			md = EVP_sha224();
6067 			break;
6068 		default: /* it should not happen, hash_alg is checked earlier */
6069 			/* fall through */
6070 		case CKM_SHA256:
6071 			md = EVP_sha256();
6072 			break;
6073 		case CKM_SHA384:
6074 			md = EVP_sha384();
6075 			break;
6076 		case CKM_SHA512:
6077 			md = EVP_sha512();
6078 			break;
6079 		}
6080 		if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) {
6081 			EVP_PKEY_CTX_free(ctx);
6082 			EVP_PKEY_free(pkey);
6083 			printf("set md failed, returning\n");
6084 			return 0;
6085 		}
6086 		switch (mgf) {
6087 		case CKG_MGF1_SHA1:
6088 			md = EVP_sha1();
6089 			break;
6090 		case CKG_MGF1_SHA224:
6091 			md = EVP_sha224();
6092 			break;
6093 		default:
6094 			printf("mgf %s unknown, defaulting to CKG_MGF1_SHA256\n", p11_mgf_to_name(mgf));
6095 			mgf = CKG_MGF1_SHA256;
6096 			/* fall through */
6097 		case CKG_MGF1_SHA256:
6098 			md = EVP_sha256();
6099 			break;
6100 		case CKG_MGF1_SHA384:
6101 			md = EVP_sha384();
6102 			break;
6103 		case CKG_MGF1_SHA512:
6104 			md = EVP_sha512();
6105 			break;
6106 		}
6107 		if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) <= 0) {
6108 			EVP_PKEY_CTX_free(ctx);
6109 			EVP_PKEY_free(pkey);
6110 			printf("set mgf1 md failed, returning\n");
6111 			return 0;
6112 		}
6113 #else
6114 		if (hash_alg != CKM_SHA_1) {
6115 			printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n");
6116 			return 0;
6117 		}
6118 #endif
6119 	}
6120 
6121 	size_t out_len = sizeof(encrypted);
6122 	if (EVP_PKEY_encrypt(ctx, encrypted, &out_len, orig_data, in_len) <= 0) {
6123 		EVP_PKEY_CTX_free(ctx);
6124 		EVP_PKEY_free(pkey);
6125 		printf("Encryption failed, returning\n");
6126 		return 0;
6127 	}
6128 	EVP_PKEY_CTX_free(ctx);
6129 	EVP_PKEY_free(pkey);
6130 	encrypted_len = out_len;
6131 
6132 	/* set "default" MGF and hash algorithms. We can overwrite MGF later */
6133 	switch (mech_type) {
6134 	case CKM_RSA_PKCS_OAEP:
6135 		oaep_params.hashAlg = hash_alg;
6136 		oaep_params.mgf = mgf;
6137 
6138 		/* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */
6139 		oaep_params.source = 0UL;  /* empty encoding parameter (label) */
6140 		oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */
6141 		oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */
6142 
6143 		/* If an RSA-OAEP mechanism, it needs parameters */
6144 		mech.pParameter = &oaep_params;
6145 		mech.ulParameterLen = sizeof(oaep_params);
6146 
6147 		fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n",
6148 			p11_mechanism_to_name(oaep_params.hashAlg),
6149 			p11_mgf_to_name(oaep_params.mgf),
6150 			oaep_params.source,
6151 			oaep_params.pSourceData,
6152 			oaep_params.ulSourceDataLen);
6153 		break;
6154 	case CKM_RSA_X_509:
6155 	case CKM_RSA_PKCS:
6156 		mech.pParameter = NULL;
6157 		mech.ulParameterLen = 0;
6158 		break;
6159 	default:
6160 		util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(mech_type));
6161 	}
6162 
6163 	mech.mechanism = mech_type;
6164 	rv = p11->C_DecryptInit(session, &mech, privKeyObject);
6165 	if (rv == CKR_MECHANISM_INVALID || rv == CKR_MECHANISM_PARAM_INVALID) {
6166 		printf("Mechanism not supported\n");
6167 		return 0;
6168 	}
6169 	if (rv != CKR_OK)
6170 		p11_fatal("C_DecryptInit", rv);
6171 	if (getALWAYS_AUTHENTICATE(session, privKeyObject))
6172 		login(session,CKU_CONTEXT_SPECIFIC);
6173 
6174 	data_len = encrypted_len;
6175 	rv = p11->C_Decrypt(session, encrypted, encrypted_len, data, &data_len);
6176 	if (rv != CKR_OK)
6177 		p11_fatal("C_Decrypt", rv);
6178 
6179 	failed = data_len != in_len || memcmp(orig_data, data, data_len);
6180 
6181 	if (failed) {
6182 		CK_ULONG n;
6183 
6184 		printf("resulting cleartext doesn't match input\n");
6185 		printf("    Original:");
6186 		for (n = 0; n < in_len; n++)
6187 			printf(" %02x", orig_data[n]);
6188 		printf("\n");
6189 		printf("    Decrypted:");
6190 		for (n = 0; n < data_len; n++)
6191 			printf(" %02x", data[n]);
6192 		printf("\n");
6193 		return 1;
6194 	}
6195 
6196 	printf("OK\n");
6197 	return 0;
6198 }
6199 #endif
6200 
6201 
6202 /*
6203  * Test decryption functions
6204  */
test_decrypt(CK_SESSION_HANDLE sess)6205 static int test_decrypt(CK_SESSION_HANDLE sess)
6206 {
6207 	int             errors = 0;
6208 	CK_RV           rv;
6209 	unsigned char   *id;
6210 	CK_OBJECT_HANDLE pubKeyObject, privKeyObject;
6211 	CK_MECHANISM_TYPE *mechs = NULL;
6212 	CK_SESSION_INFO sessionInfo;
6213 	CK_ULONG        j, num_mechs = 0, id_len;
6214 #ifdef ENABLE_OPENSSL
6215 	CK_ULONG        n;
6216 #endif
6217 	char 		*label;
6218 
6219 	rv = p11->C_GetSessionInfo(sess, &sessionInfo);
6220 	if (rv != CKR_OK)
6221 		p11_fatal("C_OpenSession", rv);
6222 	if (!(sessionInfo.state & CKS_RW_USER_FUNCTIONS)) {
6223 		printf("Decryption: not a R/W session, skipping decryption tests\n");
6224 		return errors;
6225 	}
6226 
6227 	num_mechs = get_mechanisms(sessionInfo.slotID, &mechs, CKF_DECRYPT);
6228 	if (num_mechs == 0) {
6229 		printf("Decrypt: not implemented\n");
6230 		return errors;
6231 	}
6232 
6233 	printf("Decryption (currently only for RSA)\n");
6234 	for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) {
6235 		printf("  testing key %ld", j);
6236 		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {
6237 			printf(" (%s)", label);
6238 			free(label);
6239 		}
6240 		if (getKEY_TYPE(sess, privKeyObject) != CKK_RSA) {
6241 			printf(" -- non-RSA, skipping\n");
6242 			continue;
6243 		}
6244 		if (!getDECRYPT(sess, privKeyObject)) {
6245 			printf(" -- can't be used to decrypt, skipping\n");
6246 			continue;
6247 		}
6248 
6249 		if ((id = getID(sess, privKeyObject, &id_len)) != NULL) {
6250 			int r;
6251 
6252 			r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, id_len, 0);
6253 			free(id);
6254 			if (r == 0) {
6255 				printf(" -- can't find corresponding public key, skipping\n");
6256 				continue;
6257 			}
6258 		}
6259 		else {
6260 			printf(" -- can't get the ID for looking up the public key, skipping\n");
6261 			continue;
6262 		}
6263 
6264 		printf("\n");
6265 
6266 #ifndef ENABLE_OPENSSL
6267 		printf("No OpenSSL support, unable to validate decryption\n");
6268 #else
6269 		for (n = 0; n < num_mechs; n++) {
6270 			switch (mechs[n]) {
6271 			case CKM_RSA_PKCS:
6272 			case CKM_RSA_PKCS_OAEP:
6273 			case CKM_RSA_X_509:
6274 				break;
6275 			default:
6276 				printf(" -- mechanism can't be used to decrypt, skipping\n");
6277 				continue;
6278 			}
6279 
6280 			errors += encrypt_decrypt(sess, mechs[n], privKeyObject);
6281 		}
6282 #endif
6283 	}
6284 
6285 	free(mechs);
6286 	return errors;
6287 }
6288 
test_random(CK_SESSION_HANDLE session)6289 static int test_random(CK_SESSION_HANDLE session)
6290 {
6291 	CK_BYTE buf1[100], buf2[100];
6292 	CK_BYTE seed1[100];
6293 	CK_RV rv;
6294 	int errors = 0;
6295 
6296 	printf("C_SeedRandom() and C_GenerateRandom():\n");
6297 
6298 	rv = p11->C_SeedRandom(session, seed1, 100);
6299 	if (rv == CKR_RANDOM_NO_RNG) {
6300 		printf("  RNG not available\n");
6301 		return 0;
6302 	}
6303 
6304 	if (rv == CKR_RANDOM_SEED_NOT_SUPPORTED || rv == CKR_FUNCTION_NOT_SUPPORTED)
6305 		printf("  seeding (C_SeedRandom) not supported\n");
6306 	else if (rv != CKR_OK) {
6307 		p11_perror("C_SeedRandom", rv);
6308 		return 1;
6309 	}
6310 
6311 	rv = p11->C_GenerateRandom(session, buf1, 10);
6312 	if (rv != CKR_OK) {
6313 		p11_perror("C_GenerateRandom", rv);
6314 		return 1;
6315 	}
6316 
6317 	rv = p11->C_GenerateRandom(session, buf1, 100);
6318 	if (rv != CKR_OK) {
6319 		p11_perror("C_GenerateRandom(buf1,100)", rv);
6320 		return 1;
6321 	}
6322 
6323 	rv = p11->C_GenerateRandom(session, buf1, 0);
6324 	if (rv != CKR_OK) {
6325 		p11_perror("C_GenerateRandom(buf1,0)", rv);
6326 		return 1;
6327 	}
6328 
6329 	rv = p11->C_GenerateRandom(session, buf2, 100);
6330 	if (rv != CKR_OK) {
6331 		p11_perror("C_GenerateRandom(buf2,100)", rv);
6332 		return 1;
6333 	}
6334 
6335 	if (memcmp(buf1, buf2, 100) == 0) {
6336 		printf("  ERR: C_GenerateRandom returned twice the same value!!!\n");
6337 		errors++;
6338 	}
6339 
6340 	printf("  seems to be OK\n");
6341 
6342 	return 0;
6343 }
6344 
test_card_detection(int wait_for_event)6345 static int test_card_detection(int wait_for_event)
6346 {
6347 	char buffer[256];
6348 	CK_SLOT_ID slot_id;
6349 	CK_RV rv;
6350 
6351 	printf("Testing card detection using %s\n",
6352 		wait_for_event? "C_WaitForSlotEvent()" : "C_GetSlotList()");
6353 
6354 	while (1) {
6355 		printf("Please press return to continue, x to exit: ");
6356 		fflush(stdout);
6357 		if (fgets(buffer, sizeof(buffer), stdin) == NULL
6358 		|| buffer[0] == 'x')
6359 			break;
6360 
6361 		if (wait_for_event) {
6362 			printf("Calling C_WaitForSlotEvent: ");
6363 			fflush(stdout);
6364 			rv = p11->C_WaitForSlotEvent(0, &slot_id, NULL);
6365 			if (rv != CKR_OK) {
6366 				printf("failed.\n");
6367 				p11_perror("C_WaitForSlotEvent", rv);
6368 				return 1;
6369 			}
6370 			printf("event on slot 0x%lx\n", slot_id);
6371 		}
6372 		list_slots(0, 1, 1);
6373 	}
6374 
6375 	return 0;
6376 }
6377 
p11_test(CK_SESSION_HANDLE session)6378 static int p11_test(CK_SESSION_HANDLE session)
6379 {
6380 	int errors = 0;
6381 
6382 	errors += test_random(session);
6383 
6384 	errors += test_digest(session);
6385 
6386 	errors += test_signature(session);
6387 
6388 	errors += test_verify(session);
6389 
6390 	errors += test_unwrap(session);
6391 
6392 	errors += test_decrypt(session);
6393 
6394 	if (errors == 0)
6395 		printf("No errors\n");
6396 	else
6397 		printf("%d errors\n", errors);
6398 
6399 	return errors;
6400 }
6401 
6402 /* Does about the same as Mozilla does when you go to an on-line CA
6403  * for obtaining a certificate: key pair generation, signing the
6404  * cert request + some other tests, writing certs and changing
6405  * some attributes.
6406  */
test_kpgen_certwrite(CK_SLOT_ID slot,CK_SESSION_HANDLE session)6407 static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
6408 {
6409 	CK_MECHANISM		mech = {CKM_RSA_PKCS, NULL_PTR, 0};
6410 	CK_MECHANISM_TYPE	*mech_type = NULL;
6411 	CK_OBJECT_HANDLE	pub_key, priv_key;
6412 	CK_ULONG		i, num_mechs = 0;
6413 	CK_RV			rv;
6414 	CK_BYTE			buf[20], *tmp;
6415 	CK_BYTE			md5_and_digestinfo[34] = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
6416 	CK_BYTE			*data, sig[512];
6417 	CK_ULONG		data_len, sig_len;
6418 	CK_BYTE			id[] = "abcdefghijklmnopqrst";
6419 	CK_ULONG		id_len = 20, mod_len = 0;
6420 	CK_BYTE			*label = (CK_BYTE *) "Just a label";
6421 	CK_ULONG		label_len = 12;
6422 	CK_ATTRIBUTE		attribs[3] = {
6423 		{CKA_ID, id, id_len},
6424 		{CKA_LABEL, label, label_len},
6425 		{CKA_SUBJECT, (void *) "This won't be used in our lib", 29}
6426 	};
6427 	FILE			*f;
6428 	CK_FUNCTION_LIST_PTR	p11_v2 = NULL;
6429 
6430 	if (!opt_object_id_len) {
6431 		fprintf(stderr, "ERR: must give an ID, e.g.: --id 01\n");
6432 		return session;
6433 	}
6434 	if (!opt_key_type) {
6435 		printf("ERR: must give an RSA key type, e.g.: --key-type RSA:1024\n");
6436 		return session;
6437 	}
6438 	printf("\n*** We already opened a session and logged in ***\n");
6439 
6440 	num_mechs = get_mechanisms(slot, &mech_type, -1);
6441 	for (i = 0; i < num_mechs; i++) {
6442 		if (mech_type[i] == CKM_RSA_PKCS_KEY_PAIR_GEN)
6443 			break;
6444 	}
6445 	if (i == num_mechs) {
6446 		fprintf(stderr, "ERR: no \"CKM_RSA_PKCS_KEY_PAIR_GEN\" found in the mechanism list\n");
6447 		return session;
6448 	}
6449 
6450 	f = fopen(opt_file_to_write, "rb");
6451 	if (f == NULL)
6452 		util_fatal("Couldn't open file \"%s\"", opt_file_to_write);
6453 	fclose(f);
6454 
6455 	/* Get for a not-yet-existing ID */
6456 	while(find_object(session, CKO_PRIVATE_KEY, &priv_key, id, id_len, 0))
6457 		id[0]++;
6458 
6459 	printf("\n*** Generating a %s key pair ***\n", opt_key_type);
6460 
6461 	if (!gen_keypair(slot, session, &pub_key, &priv_key, opt_key_type)) {
6462 		printf("ERR: cannot generate new key pair\n");
6463 		return session;
6464 	}
6465 
6466 	tmp = getID(session, priv_key, &i);
6467 	if (i == 0) {
6468 		fprintf(stderr, "ERR: newly generated private key has no (or an empty) CKA_ID\n");
6469 		return session;
6470 	}
6471 	opt_object_id_len = (size_t) i;
6472 	memcpy(opt_object_id, tmp, opt_object_id_len);
6473 
6474 	/* This is done in NSS */
6475 	getMODULUS(session, priv_key, &mod_len);
6476 	if (mod_len < 5 || mod_len > 10000) { /* should be reasonable limits */
6477 		fprintf(stderr, "ERR: GetAttribute(privkey, CKA_MODULUS) doesn't seem to work\n");
6478 		return session;
6479 	}
6480 
6481 	printf("\n*** Changing the CKA_ID of private and public key into one of 20 bytes ***\n");
6482 
6483 	rv = p11->C_SetAttributeValue(session, priv_key, attribs, 1);
6484 	if (rv != CKR_OK)
6485 		p11_fatal("C_SetAttributeValue(priv_key)", rv);
6486 
6487 	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 1);
6488 	if (rv != CKR_OK)
6489 		p11_fatal("C_SetAttributeValue(pub_key)", rv);
6490 
6491 	printf("\n*** Do a signature and verify it (presumably to test the keys) ***\n");
6492 
6493 	data = buf;
6494 	data_len = 20;
6495 	rv = p11->C_SignInit(session, &mech, priv_key);
6496 	if (rv != CKR_OK)
6497 		p11_fatal("C_SignInit", rv);
6498 	if (getALWAYS_AUTHENTICATE(session, priv_key))
6499 		login(session,CKU_CONTEXT_SPECIFIC);
6500 
6501 	rv = p11->C_Sign(session, data, data_len, NULL, &sig_len);
6502 	if (rv != CKR_OK)
6503 		p11_fatal("C_Sign", rv);
6504 	sig_len = 20;
6505 	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);
6506 	if (rv != CKR_BUFFER_TOO_SMALL) {
6507 		fprintf(stderr, "ERR: C_Sign() didn't return CKR_BUFFER_TO_SMALL but %s\n", CKR2Str(rv));
6508 		return session;
6509 	}
6510 	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);
6511 	if (rv != CKR_OK)
6512 		p11_fatal("C_Sign", rv);
6513 
6514 	rv = p11->C_VerifyInit(session, &mech, pub_key);
6515 	if (rv != CKR_OK)
6516 		p11_fatal("C_VerifyInit", rv);
6517 	rv = p11->C_Verify(session, data, data_len, sig, sig_len);
6518 	if (rv != CKR_OK)
6519 		p11_fatal("C_Verify", rv);
6520 
6521 	/* Sign the certificate request */
6522 
6523 	printf("\n*** Signing the certificate request ***\n");
6524 
6525 	data = md5_and_digestinfo;
6526 	data_len = 20;
6527 	rv = p11->C_SignInit(session, &mech, priv_key);
6528 	if (rv != CKR_OK)
6529 		p11_fatal("C_SignInit", rv);
6530 	if (getALWAYS_AUTHENTICATE(session, priv_key))
6531 		login(session,CKU_CONTEXT_SPECIFIC);
6532 
6533 	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);
6534 	if (rv != CKR_OK)
6535 		p11_fatal("C_Sign", rv);
6536 
6537 	printf("\n*** Changing the CKA_LABEL, CKA_ID and CKA_SUBJECT of the public key ***\n");
6538 
6539 	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 3);
6540 	if (rv != CKR_OK)
6541 		p11_fatal("C_SetAttributeValue", rv);
6542 
6543 	printf("*** Deleting the private and the public key again ***\n");
6544 
6545 	rv = p11->C_DestroyObject(session, priv_key);
6546 	if (rv != CKR_OK)
6547 		p11_fatal("C_DestroyObject()", rv);
6548 	rv = p11->C_DestroyObject(session, pub_key);
6549 	if (rv != CKR_OK)
6550 		p11_fatal("C_DestroyObject()", rv);
6551 
6552 	printf("\n*** Logging off and releasing pkcs11 lib ***\n");
6553 
6554 	rv = p11->C_CloseAllSessions(slot);
6555 	if (rv != CKR_OK)
6556 		p11_fatal("CloseAllSessions", rv);
6557 
6558 	rv = p11->C_Finalize(NULL);
6559 	if (rv != CKR_OK)
6560 		p11_fatal("Finalize", rv);
6561 
6562 	C_UnloadModule(module);
6563 
6564 	/* Now we assume the user turns of her PC and comes back tomorrow to see
6565 	 * if here cert is already made and to install it (as is done next) */
6566 
6567 	printf("\n*** In real life, the cert req should now be sent to the CA ***\n");
6568 
6569 	printf("\n*** Loading the pkcs11 lib, opening a session and logging in ***\n");
6570 
6571 	module = C_LoadModule(opt_module, &p11_v2);
6572 	if (module == NULL)
6573 		util_fatal("Failed to load pkcs11 module");
6574 	p11 = (CK_FUNCTION_LIST_3_0_PTR ) p11_v2;
6575 
6576 	rv = p11->C_Initialize(c_initialize_args_ptr);
6577 	if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
6578 		printf("\n*** Cryptoki library has already been initialized ***\n");
6579 	else if (rv != CKR_OK)
6580 		p11_fatal("C_Initialize", rv);
6581 
6582 	rv = p11->C_OpenSession(opt_slot, CKF_SERIAL_SESSION| CKF_RW_SESSION,
6583 			NULL, NULL, &session);
6584 	if (rv != CKR_OK)
6585 		p11_fatal("C_OpenSession", rv);
6586 
6587 	login(session, CKU_USER);
6588 
6589 	printf("\n*** Put a cert on the card (NOTE: doesn't correspond with the key!) ***\n");
6590 
6591 	opt_object_class = CKO_CERTIFICATE;
6592 	memcpy(opt_object_id, id, id_len);
6593 	opt_object_id_len = id_len;
6594 	opt_object_label = (char *) label;
6595 	if (!write_object(session))
6596 		util_fatal("Failed to write certificate");
6597 	if (!delete_object(session))
6598 		util_fatal("Failed to delete certificate");
6599 
6600 	printf("\n==> OK, successful! Should work with Mozilla\n");
6601 	return session;
6602 }
6603 
6604 
test_ec(CK_SLOT_ID slot,CK_SESSION_HANDLE session)6605 static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
6606 {
6607 	CK_MECHANISM		mech = {CKM_ECDSA_SHA1, NULL_PTR, 0};
6608 	CK_MECHANISM_TYPE	*mech_type = NULL;
6609 	CK_OBJECT_HANDLE	pub_key, priv_key;
6610 	CK_ULONG		i, num_mechs = 0;
6611 	CK_RV			rv;
6612 	CK_BYTE			*tmp;
6613 	CK_BYTE			*data_to_sign = (CK_BYTE *)"My Heart's in the Highland";
6614 	CK_BYTE			*data, sig[512];
6615 	CK_ULONG		data_len, sig_len;
6616 	CK_BYTE			*id = (CK_BYTE *) "abcdefghijklmnopqrst";
6617 	CK_ULONG		id_len = strlen((char *)id), ec_params_len, ec_point_len;
6618 	CK_BYTE			*label = (CK_BYTE *) "Just a label";
6619 	CK_ULONG		label_len = 12;
6620 	CK_ATTRIBUTE		attribs[3] = {
6621 		{CKA_ID, id, id_len},
6622 		{CKA_LABEL, label, label_len},
6623 		{CKA_SUBJECT, (void *) "This won't be used in our lib", 29}
6624 	};
6625 
6626 	if (!opt_object_id_len) {
6627 		fprintf(stderr, "ERR: must give an ID, e.g.: --id 01\n");
6628 		return;
6629 	}
6630 	if (!opt_key_type) {
6631 		fprintf(stderr, "ERR: must give an EC key type, e.g.: --key-type EC:secp256r1\n");
6632 		return;
6633 	}
6634 
6635 	printf("\n*** We already opened a session and logged in ***\n");
6636 
6637 	num_mechs = get_mechanisms(slot, &mech_type, -1);
6638 	for (i = 0; i < num_mechs; i++)
6639 		if (mech_type[i] == CKM_EC_KEY_PAIR_GEN)
6640 			break;
6641 	if (i == num_mechs) {
6642 		printf("warning: no 'CKM_EC_KEY_PAIR_GEN' found in the mechanism list\n");
6643 		//return;
6644 	}
6645 
6646 	printf("*** Generating EC key pair ***\n");
6647 	if (!gen_keypair(slot, session, &pub_key, &priv_key, opt_key_type))
6648 		return;
6649 
6650 	tmp = getID(session, priv_key, &i);
6651 	if (i == 0) {
6652 		printf("ERR: newly generated private key has no (or an empty) CKA_ID\n");
6653 		return;
6654 	}
6655 	i = (size_t) opt_object_id_len;
6656 	memcpy(opt_object_id, tmp, opt_object_id_len);
6657 
6658 	/* This is done in NSS */
6659 	getEC_PARAMS(session, priv_key, &ec_params_len);
6660 	if (ec_params_len < 5 || ec_params_len > 10000) {
6661 		printf("ERR: GetAttribute(privkey, CKA_EC_PARAMS) doesn't seem to work\n");
6662 		return;
6663 	}
6664 	getEC_POINT(session, pub_key, &ec_point_len);
6665 	if (ec_point_len < 5 || ec_point_len > 10000) {
6666 		printf("ERR: GetAttribute(pubkey, CKA_EC_POINT) doesn't seem to work\n");
6667 		return;
6668 	}
6669 
6670 	printf("*** Changing the CKA_ID of private and public key into one of 20 bytes ***\n");
6671 	rv = p11->C_SetAttributeValue(session, priv_key, attribs, 1);
6672 	if (rv != CKR_OK)
6673 		p11_warn("C_SetAttributeValue(priv_key)", rv);
6674 
6675 	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 1);
6676 	if (rv != CKR_OK)
6677 		p11_warn("C_SetAttributeValue(pub_key)", rv);
6678 
6679 	printf("*** Doing a signature ***\n");
6680 	data = data_to_sign;
6681 	data_len = strlen((char *)data_to_sign);
6682 	rv = p11->C_SignInit(session, &mech, priv_key);
6683 	if (rv != CKR_OK)
6684 		p11_fatal("C_SignInit", rv);
6685 	if (getALWAYS_AUTHENTICATE(session, priv_key))
6686 		login(session,CKU_CONTEXT_SPECIFIC);
6687 	rv = p11->C_Sign(session, data, data_len, NULL, &sig_len);
6688 	if (rv != CKR_OK)
6689 		p11_fatal("C_Sign", rv);
6690 	sig_len -= 20;
6691 	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);
6692 	if (rv != CKR_BUFFER_TOO_SMALL) {
6693 		printf("warning: C_Sign() didn't return CKR_BUFFER_TO_SMALL but %s\n", CKR2Str(rv));
6694 		// return;
6695 	}
6696 	sig_len += 20;
6697 	// re-doing C_SignInit after C_SignFinal to avoid CKR_OPERATION_NOT_INITIALIZED for CardOS
6698 	rv = p11->C_SignFinal(session, sig, &sig_len);
6699 	if (rv != CKR_OK) {
6700 		p11_warn("C_SignFinal", rv);
6701 	}
6702 	rv = p11->C_SignInit(session, &mech, priv_key);
6703 	if (rv != CKR_OK)
6704 		p11_fatal("C_SignInit", rv);
6705 	if (getALWAYS_AUTHENTICATE(session, priv_key))
6706 		login(session,CKU_CONTEXT_SPECIFIC);
6707 	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);
6708 	if (rv != CKR_OK)
6709 		p11_fatal("C_Sign", rv);
6710 
6711 	printf("*** Changing the CKA_LABEL, CKA_ID and CKA_SUBJECT of the public key ***\n");
6712 	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 3);
6713 	if (rv != CKR_OK)
6714 		p11_warn("C_SetAttributeValue(pub_key)", rv);
6715 
6716 	printf("*** Deleting the private and the public key again ***\n");
6717 	rv = p11->C_DestroyObject(session, priv_key);
6718 	if (rv != CKR_OK)
6719 		p11_fatal("C_DestroyObject()", rv);
6720 	rv = p11->C_DestroyObject(session, pub_key);
6721 	if (rv != CKR_OK)
6722 		p11_fatal("C_DestroyObject()", rv);
6723 
6724 	printf("==> OK\n");
6725 }
6726 
6727 #ifndef _WIN32
test_fork(void)6728 static void test_fork(void)
6729 {
6730 	CK_RV rv;
6731 	pid_t pid = fork();
6732 
6733 	if (!pid) {
6734 		printf("*** Calling C_Initialize in forked child process ***\n");
6735 		rv = p11->C_Initialize(c_initialize_args_ptr);
6736 		if (rv != CKR_OK)
6737 			p11_fatal("C_Initialize in child\n", rv);
6738 		exit(0);
6739 	} else if (pid < 0) {
6740 		util_fatal("Failed to fork for test: %s", strerror(errno));
6741 	} else {
6742 		int st;
6743 		waitpid(pid, &st, 0);
6744 		if (!WIFEXITED(st) || WEXITSTATUS(st))
6745 			util_fatal("Child process exited with status %d", st);
6746 	}
6747 
6748 }
6749 #endif
6750 
generate_random(CK_SESSION_HANDLE session)6751 static void generate_random(CK_SESSION_HANDLE session)
6752 {
6753 	CK_RV rv;
6754 	CK_BYTE *buf;
6755 	FILE *out;
6756 
6757 	buf = malloc(opt_random_bytes);
6758 	if (!buf)
6759 		util_fatal("Not enough memory to allocate random data buffer");
6760 
6761 	rv = p11->C_GenerateRandom(session, buf, opt_random_bytes);
6762 	if (rv != CKR_OK)
6763 		util_fatal("Could not generate random bytes");
6764 
6765 	if (opt_output) {
6766 		out = fopen(opt_output, "wb");
6767 		if (out==NULL)
6768 			util_fatal("Cannot open '%s'", opt_output);
6769 	}
6770 	else
6771 		out = stdout;
6772 
6773 	if (fwrite(buf, 1, opt_random_bytes, out) != opt_random_bytes)
6774 		util_fatal("Cannot write to '%s'", opt_output);
6775 
6776 	if (opt_output)
6777 		fclose(out);
6778 
6779 	free(buf);
6780 }
6781 
p11_flag_names(struct flag_info * list,CK_FLAGS value)6782 static const char *p11_flag_names(struct flag_info *list, CK_FLAGS value)
6783 {
6784 	static char	buffer[1024];
6785 	const char	*sepa = "";
6786 
6787 	buffer[0] = '\0';
6788 	while (list->value) {
6789 		if (list->value & value) {
6790 			strlcat(buffer, sepa, sizeof buffer);
6791 			strlcat(buffer, list->name, sizeof buffer);
6792 			value &= ~list->value;
6793 			sepa = ", ";
6794 		}
6795 		list++;
6796 	}
6797 	if (value) {
6798 		sprintf(buffer+strlen(buffer),
6799 			"%sother flags=0x%x", sepa,
6800 			(unsigned int) value);
6801 	}
6802 	return buffer;
6803 }
6804 
p11_slot_info_flags(CK_FLAGS value)6805 static const char *p11_slot_info_flags(CK_FLAGS value)
6806 {
6807 	static struct flag_info	slot_flags[] = {
6808 		{ CKF_TOKEN_PRESENT, "token present" },
6809 		{ CKF_REMOVABLE_DEVICE, "removable device" },
6810 		{ CKF_HW_SLOT, "hardware slot" },
6811 		{ 0, NULL }
6812 	};
6813 
6814 	return p11_flag_names(slot_flags, value);
6815 }
6816 
p11_token_info_flags(CK_FLAGS value)6817 static const char *p11_token_info_flags(CK_FLAGS value)
6818 {
6819 	static struct flag_info	slot_flags[] = {
6820 		{ CKF_LOGIN_REQUIRED, "login required" },
6821 		{ CKF_PROTECTED_AUTHENTICATION_PATH, "PIN pad present" },
6822 		{ CKF_RNG, "rng" },
6823 		{ CKF_SO_PIN_COUNT_LOW, "SO PIN count low" },
6824 		{ CKF_SO_PIN_FINAL_TRY, "final SO PIN try" },
6825 		{ CKF_SO_PIN_LOCKED, "SO PIN locked" },
6826 		{ CKF_SO_PIN_TO_BE_CHANGED, "SO PIN to be changed"},
6827 		{ CKF_TOKEN_INITIALIZED, "token initialized" },
6828 		{ CKF_USER_PIN_COUNT_LOW, "user PIN count low" },
6829 		{ CKF_USER_PIN_FINAL_TRY, "final user PIN try" },
6830 		{ CKF_USER_PIN_INITIALIZED, "PIN initialized" },
6831 		{ CKF_USER_PIN_LOCKED, "user PIN locked" },
6832 		{ CKF_USER_PIN_TO_BE_CHANGED, "user PIN to be changed"},
6833 		{ CKF_WRITE_PROTECTED, "readonly" },
6834 		{ 0, NULL }
6835 	};
6836 
6837 	return p11_flag_names(slot_flags, value);
6838 }
6839 
p11_utf8_to_local(CK_UTF8CHAR * string,size_t len)6840 static const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len)
6841 {
6842 	static char	buffer[512];
6843 	size_t		n, m;
6844 
6845 	while (len && string[len-1] == ' ')
6846 		len--;
6847 
6848 	/* For now, simply copy this thing */
6849 	for (n = m = 0; n < sizeof(buffer) - 1; n++) {
6850 		if (m >= len)
6851 			break;
6852 		buffer[n] = string[m++];
6853 	}
6854 	buffer[n] = '\0';
6855 	return buffer;
6856 }
6857 
p11_fatal(const char * func,CK_RV rv)6858 static void p11_fatal(const char *func, CK_RV rv)
6859 {
6860 	if (p11)
6861 		p11->C_Finalize(NULL_PTR);
6862 	if (module)
6863 		C_UnloadModule(module);
6864 
6865 	util_fatal("PKCS11 function %s failed: rv = %s (0x%0x)", func, CKR2Str(rv), (unsigned int) rv);
6866 }
6867 
p11_warn(const char * func,CK_RV rv)6868 static void p11_warn(const char *func, CK_RV rv)
6869 {
6870 	if (!suppress_warn)
6871 		util_warn("PKCS11 function %s failed: rv = %s (0x%0x)\n", func, CKR2Str(rv), (unsigned int) rv);
6872 }
6873 
p11_perror(const char * msg,CK_RV rv)6874 static void p11_perror(const char *msg, CK_RV rv)
6875 {
6876 	fprintf(stderr, "  ERR: %s failed: %s (0x%0x)\n", msg, CKR2Str(rv), (unsigned int) rv);
6877 }
6878 
hex_to_bin(const char * in,unsigned char * out,size_t * outlen)6879 static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen)
6880 {
6881 	size_t left, count = 0;
6882 	int nybbles = 2;
6883 
6884 	if (in == NULL || *in == '\0') {
6885 		*outlen = 0;
6886 		return 1;
6887 	}
6888 
6889 	left = *outlen;
6890 
6891 	if (strlen(in) % 2)
6892 		nybbles = 1; // any leading zero in output should be in most-significant byte, not last one!
6893 	while (*in != '\0') {
6894 		int byte = 0;
6895 
6896 		while (nybbles-- && *in && *in != ':') {
6897 			char c;
6898 			byte <<= 4;
6899 			c = *in++;
6900 			if ('0' <= c && c <= '9')
6901 				c -= '0';
6902 			else
6903 			if ('a' <= c && c <= 'f')
6904 				c = c - 'a' + 10;
6905 			else
6906 			if ('A' <= c && c <= 'F')
6907 				c = c - 'A' + 10;
6908 			else {
6909 				fprintf(stderr, "hex_to_bin(): invalid char '%c' in hex string\n", c);
6910 				*outlen = 0;
6911 				return 0;
6912 			}
6913 			byte |= c;
6914 		}
6915 		if (*in == ':')
6916 			in++;
6917 		if (left <= 0) {
6918 			fprintf(stderr, "hex_to_bin(): hex string too long");
6919 			*outlen = 0;
6920 			return 0;
6921 		}
6922 		out[count++] = (unsigned char) byte;
6923 		left--;
6924 		nybbles = 2;
6925 	}
6926 
6927 	*outlen = count;
6928 	return 1;
6929 }
6930 
pseudo_randomize(unsigned char * data,size_t dataLen)6931 static void pseudo_randomize(unsigned char *data, size_t dataLen)
6932 {
6933 	size_t i = 0;
6934 	/* initialization with some data */
6935 	while (i < dataLen) {
6936 		*data = rand() & 0xFF;
6937 		data++;
6938 		i++;
6939 	}
6940 }
6941 
6942 static struct mech_info	p11_mechanisms[] = {
6943       { CKM_RSA_PKCS_KEY_PAIR_GEN,	"RSA-PKCS-KEY-PAIR-GEN", NULL },
6944       { CKM_RSA_PKCS,		"RSA-PKCS",	NULL },
6945       { CKM_RSA_9796,		"RSA-9796",	NULL },
6946       { CKM_RSA_X_509,		"RSA-X-509",	NULL },
6947       { CKM_MD2_RSA_PKCS,	"MD2-RSA-PKCS",	NULL },
6948       { CKM_MD5_RSA_PKCS,	"MD5-RSA-PKCS",	"rsa-md5" },
6949       { CKM_SHA1_RSA_PKCS,	"SHA1-RSA-PKCS",	"rsa-sha1" },
6950       { CKM_SHA224_RSA_PKCS,	"SHA224-RSA-PKCS",	"rsa-sha224" },
6951       { CKM_SHA256_RSA_PKCS,	"SHA256-RSA-PKCS",	"rsa-sha256" },
6952       { CKM_SHA384_RSA_PKCS,	"SHA384-RSA-PKCS",	"rsa-sha384" },
6953       { CKM_SHA512_RSA_PKCS,	"SHA512-RSA-PKCS",	"rsa-sha512" },
6954       { CKM_RIPEMD128_RSA_PKCS,	"RIPEMD128-RSA-PKCS",	NULL },
6955       { CKM_RIPEMD160_RSA_PKCS,	"RIPEMD160-RSA-PKCS",	"rsa-ripemd160" },
6956       { CKM_RSA_PKCS_OAEP,	"RSA-PKCS-OAEP",	NULL },
6957       { CKM_RSA_X9_31_KEY_PAIR_GEN,"RSA-X9-31-KEY-PAIR-GEN", NULL },
6958       { CKM_RSA_X9_31,		"RSA-X9-31",	NULL },
6959       { CKM_SHA1_RSA_X9_31,	"SHA1-RSA-X9-31",	NULL },
6960       { CKM_RSA_PKCS_PSS,	"RSA-PKCS-PSS",	NULL },
6961       { CKM_SHA1_RSA_PKCS_PSS,	"SHA1-RSA-PKCS-PSS",	"rsa-pss-sha1" },
6962       { CKM_SHA224_RSA_PKCS_PSS,"SHA224-RSA-PKCS-PSS",	"rsa-pss-sha224" },
6963       { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS",	"rsa-pss-sha256" },
6964       { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS",	"rsa-pss-sha384" },
6965       { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS",	"rsa-pss-sha512" },
6966       { CKM_DSA_KEY_PAIR_GEN,	"DSA-KEY-PAIR-GEN",	NULL },
6967       { CKM_DSA,		"DSA",	NULL },
6968       { CKM_DSA_SHA1,		"DSA-SHA1", NULL },
6969       { CKM_DSA_SHA224,		"DSA-SHA224", NULL },
6970       { CKM_DSA_SHA256,		"DSA-SHA256", NULL },
6971       { CKM_DSA_SHA384,		"DSA-SHA384", NULL },
6972       { CKM_DSA_SHA512,		"DSA-SHA512", NULL },
6973       { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN", NULL },
6974       { CKM_DH_PKCS_DERIVE,	"DH-PKCS-DERIVE", NULL },
6975       { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN", NULL },
6976       { CKM_X9_42_DH_DERIVE,	"X9-42-DH-DERIVE", NULL },
6977       { CKM_X9_42_DH_HYBRID_DERIVE,"X9-42-DH-HYBRID-DERIVE", NULL },
6978       { CKM_X9_42_MQV_DERIVE,	"X9-42-MQV-DERIVE", NULL },
6979       { CKM_RC2_KEY_GEN,	"RC2-KEY-GEN", NULL },
6980       { CKM_RC2_ECB,		"RC2-ECB", NULL },
6981       { CKM_RC2_CBC,		"RC2-CBC", NULL },
6982       { CKM_RC2_MAC,		"RC2-MAC", NULL },
6983       { CKM_RC2_MAC_GENERAL,	"RC2-MAC-GENERAL", NULL },
6984       { CKM_RC2_CBC_PAD,	"RC2-CBC-PAD", NULL },
6985       { CKM_RC4_KEY_GEN,	"RC4-KEY-GEN", NULL },
6986       { CKM_RC4,		"RC4", NULL },
6987       { CKM_DES_KEY_GEN,	"DES-KEY-GEN", NULL },
6988       { CKM_DES_ECB,		"DES-ECB", NULL },
6989       { CKM_DES_CBC,		"DES-CBC", NULL },
6990       { CKM_DES_MAC,		"DES-MAC", NULL },
6991       { CKM_DES_MAC_GENERAL,	"DES-MAC-GENERAL", NULL },
6992       { CKM_DES_CBC_PAD,	"DES-CBC-PAD", NULL },
6993       { CKM_DES2_KEY_GEN,	"DES2-KEY-GEN", NULL },
6994       { CKM_DES3_KEY_GEN,	"DES3-KEY-GEN", NULL },
6995       { CKM_DES3_ECB,		"DES3-ECB", NULL },
6996       { CKM_DES3_CBC,		"DES3-CBC", NULL },
6997       { CKM_DES3_MAC,		"DES3-MAC", NULL },
6998       { CKM_DES3_MAC_GENERAL,	"DES3-MAC-GENERAL", NULL },
6999       { CKM_DES3_CBC_PAD,	"DES3-CBC-PAD", NULL },
7000       { CKM_DES3_CMAC,		"DES3-CMAC", NULL },
7001       { CKM_CDMF_KEY_GEN,	"CDMF-KEY-GEN", NULL },
7002       { CKM_CDMF_ECB,		"CDMF-ECB", NULL },
7003       { CKM_CDMF_CBC,		"CDMF-CBC", NULL },
7004       { CKM_CDMF_MAC,		"CDMF-MAC", NULL },
7005       { CKM_CDMF_MAC_GENERAL,	"CDMF-MAC-GENERAL", NULL },
7006       { CKM_CDMF_CBC_PAD,	"CDMF-CBC-PAD", NULL },
7007       { CKM_MD2,		"MD2", NULL },
7008       { CKM_MD2_HMAC,		"MD2-HMAC", NULL },
7009       { CKM_MD2_HMAC_GENERAL,	"MD2-HMAC-GENERAL", NULL },
7010       { CKM_MD5,		"MD5", NULL },
7011       { CKM_MD5_HMAC,		"MD5-HMAC", NULL },
7012       { CKM_MD5_HMAC_GENERAL,	"MD5-HMAC-GENERAL", NULL },
7013       { CKM_SHA_1,		"SHA-1", NULL },
7014       { CKM_SHA_1_HMAC,		"SHA-1-HMAC", NULL },
7015       { CKM_SHA_1_HMAC_GENERAL,	"SHA-1-HMAC-GENERAL", NULL },
7016       { CKM_SHA224,		"SHA224", NULL },
7017       { CKM_SHA224_HMAC,	"SHA224-HMAC", NULL },
7018       { CKM_SHA256,		"SHA256", NULL },
7019       { CKM_SHA256_HMAC,	"SHA256-HMAC", NULL },
7020       { CKM_SHA384,		"SHA384", NULL },
7021       { CKM_SHA384_HMAC,	"SHA384-HMAC", NULL },
7022       { CKM_SHA512,		"SHA512", NULL },
7023       { CKM_SHA512_HMAC,	"SHA512-HMAC", NULL },
7024       { CKM_RIPEMD128,		"RIPEMD128", NULL },
7025       { CKM_RIPEMD128_HMAC,	"RIPEMD128-HMAC", NULL },
7026       { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL },
7027       { CKM_RIPEMD160,		"RIPEMD160", NULL },
7028       { CKM_RIPEMD160_HMAC,	"RIPEMD160-HMAC", NULL },
7029       { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL", NULL },
7030       { CKM_CAST_KEY_GEN,	"CAST-KEY-GEN", NULL },
7031       { CKM_CAST_ECB,		"CAST-ECB", NULL },
7032       { CKM_CAST_CBC,		"CAST-CBC", NULL },
7033       { CKM_CAST_MAC,		"CAST-MAC", NULL },
7034       { CKM_CAST_MAC_GENERAL,	"CAST-MAC-GENERAL", NULL },
7035       { CKM_CAST_CBC_PAD,	"CAST-CBC-PAD", NULL },
7036       { CKM_CAST3_KEY_GEN,	"CAST3-KEY-GEN", NULL },
7037       { CKM_CAST3_ECB,		"CAST3-ECB", NULL },
7038       { CKM_CAST3_CBC,		"CAST3-CBC", NULL },
7039       { CKM_CAST3_MAC,		"CAST3-MAC", NULL },
7040       { CKM_CAST3_MAC_GENERAL,	"CAST3-MAC-GENERAL", NULL },
7041       { CKM_CAST3_CBC_PAD,	"CAST3-CBC-PAD", NULL },
7042       { CKM_CAST5_KEY_GEN,	"CAST5-KEY-GEN", NULL },
7043       { CKM_CAST5_ECB,		"CAST5-ECB", NULL },
7044       { CKM_CAST5_CBC,		"CAST5-CBC", NULL },
7045       { CKM_CAST5_MAC,		"CAST5-MAC", NULL },
7046       { CKM_CAST5_MAC_GENERAL,	"CAST5-MAC-GENERAL", NULL },
7047       { CKM_CAST5_CBC_PAD,	"CAST5-CBC-PAD", NULL },
7048       { CKM_RC5_KEY_GEN,	"RC5-KEY-GEN", NULL },
7049       { CKM_RC5_ECB,		"RC5-ECB", NULL },
7050       { CKM_RC5_CBC,		"RC5-CBC", NULL },
7051       { CKM_RC5_MAC,		"RC5-MAC", NULL },
7052       { CKM_RC5_MAC_GENERAL,	"RC5-MAC-GENERAL", NULL },
7053       { CKM_RC5_CBC_PAD,	"RC5-CBC-PAD", NULL },
7054       { CKM_IDEA_KEY_GEN,	"IDEA-KEY-GEN", NULL },
7055       { CKM_IDEA_ECB,		"IDEA-ECB", NULL },
7056       { CKM_IDEA_CBC,		"IDEA-CBC", NULL },
7057       { CKM_IDEA_MAC,		"IDEA-MAC", NULL },
7058       { CKM_IDEA_MAC_GENERAL,	"IDEA-MAC-GENERAL", NULL },
7059       { CKM_IDEA_CBC_PAD,	"IDEA-CBC-PAD", NULL },
7060       { CKM_GENERIC_SECRET_KEY_GEN,"GENERIC-SECRET-KEY-GEN", NULL },
7061       { CKM_CONCATENATE_BASE_AND_KEY,"CONCATENATE-BASE-AND-KEY", NULL },
7062       { CKM_CONCATENATE_BASE_AND_DATA,"CONCATENATE-BASE-AND-DATA", NULL },
7063       { CKM_CONCATENATE_DATA_AND_BASE,"CONCATENATE-DATA-AND-BASE", NULL },
7064       { CKM_XOR_BASE_AND_DATA,	"XOR-BASE-AND-DATA", NULL },
7065       { CKM_EXTRACT_KEY_FROM_KEY,"EXTRACT-KEY-FROM-KEY", NULL },
7066       { CKM_SSL3_PRE_MASTER_KEY_GEN,"SSL3-PRE-MASTER-KEY-GEN", NULL },
7067       { CKM_SSL3_MASTER_KEY_DERIVE,"SSL3-MASTER-KEY-DERIVE", NULL },
7068       { CKM_SSL3_KEY_AND_MAC_DERIVE,"SSL3-KEY-AND-MAC-DERIVE", NULL },
7069       { CKM_SSL3_MASTER_KEY_DERIVE_DH,"SSL3-MASTER-KEY-DERIVE-DH", NULL },
7070       { CKM_TLS_PRE_MASTER_KEY_GEN,"TLS-PRE-MASTER-KEY-GEN", NULL },
7071       { CKM_TLS_MASTER_KEY_DERIVE,"TLS-MASTER-KEY-DERIVE", NULL },
7072       { CKM_TLS_KEY_AND_MAC_DERIVE,"TLS-KEY-AND-MAC-DERIVE", NULL },
7073       { CKM_TLS_MASTER_KEY_DERIVE_DH,"TLS-MASTER-KEY-DERIVE-DH", NULL },
7074       { CKM_SSL3_MD5_MAC,	"SSL3-MD5-MAC", NULL },
7075       { CKM_SSL3_SHA1_MAC,	"SSL3-SHA1-MAC", NULL },
7076       { CKM_MD5_KEY_DERIVATION,	"MD5-KEY-DERIVATION", NULL },
7077       { CKM_MD2_KEY_DERIVATION,	"MD2-KEY-DERIVATION", NULL },
7078       { CKM_SHA1_KEY_DERIVATION,"SHA1-KEY-DERIVATION", NULL },
7079       { CKM_PBE_MD2_DES_CBC,	"PBE-MD2-DES-CBC", NULL },
7080       { CKM_PBE_MD5_DES_CBC,	"PBE-MD5-DES-CBC", NULL },
7081       { CKM_PBE_MD5_CAST_CBC,	"PBE-MD5-CAST-CBC", NULL },
7082       { CKM_PBE_MD5_CAST3_CBC,	"PBE-MD5-CAST3-CBC", NULL },
7083       { CKM_PBE_MD5_CAST5_CBC,	"PBE-MD5-CAST5-CBC", NULL },
7084       { CKM_PBE_SHA1_CAST5_CBC,	"PBE-SHA1-CAST5-CBC", NULL },
7085       { CKM_PBE_SHA1_RC4_128,	"PBE-SHA1-RC4-128", NULL },
7086       { CKM_PBE_SHA1_RC4_40,	"PBE-SHA1-RC4-40", NULL },
7087       { CKM_PBE_SHA1_DES3_EDE_CBC,"PBE-SHA1-DES3-EDE-CBC", NULL },
7088       { CKM_PBE_SHA1_DES2_EDE_CBC,"PBE-SHA1-DES2-EDE-CBC", NULL },
7089       { CKM_PBE_SHA1_RC2_128_CBC,"PBE-SHA1-RC2-128-CBC", NULL },
7090       { CKM_PBE_SHA1_RC2_40_CBC,"PBE-SHA1-RC2-40-CBC", NULL },
7091       { CKM_PKCS5_PBKD2,	"PKCS5-PBKD2", NULL },
7092       { CKM_PBA_SHA1_WITH_SHA1_HMAC,"PBA-SHA1-WITH-SHA1-HMAC", NULL },
7093       { CKM_KEY_WRAP_LYNKS,	"KEY-WRAP-LYNKS", NULL },
7094       { CKM_KEY_WRAP_SET_OAEP,	"KEY-WRAP-SET-OAEP", NULL },
7095       { CKM_SKIPJACK_KEY_GEN,	"SKIPJACK-KEY-GEN", NULL },
7096       { CKM_SKIPJACK_ECB64,	"SKIPJACK-ECB64", NULL },
7097       { CKM_SKIPJACK_CBC64,	"SKIPJACK-CBC64", NULL },
7098       { CKM_SKIPJACK_OFB64,	"SKIPJACK-OFB64", NULL },
7099       { CKM_SKIPJACK_CFB64,	"SKIPJACK-CFB64", NULL },
7100       { CKM_SKIPJACK_CFB32,	"SKIPJACK-CFB32", NULL },
7101       { CKM_SKIPJACK_CFB16,	"SKIPJACK-CFB16", NULL },
7102       { CKM_SKIPJACK_CFB8,	"SKIPJACK-CFB8", NULL },
7103       { CKM_SKIPJACK_WRAP,	"SKIPJACK-WRAP", NULL },
7104       { CKM_SKIPJACK_PRIVATE_WRAP,"SKIPJACK-PRIVATE-WRAP", NULL },
7105       { CKM_SKIPJACK_RELAYX,	"SKIPJACK-RELAYX", NULL },
7106       { CKM_KEA_KEY_PAIR_GEN,	"KEA-KEY-PAIR-GEN", NULL },
7107       { CKM_KEA_KEY_DERIVE,	"KEA-KEY-DERIVE", NULL },
7108       { CKM_FORTEZZA_TIMESTAMP,	"FORTEZZA-TIMESTAMP", NULL },
7109       { CKM_BATON_KEY_GEN,	"BATON-KEY-GEN", NULL },
7110       { CKM_BATON_ECB128,	"BATON-ECB128", NULL },
7111       { CKM_BATON_ECB96,	"BATON-ECB96", NULL },
7112       { CKM_BATON_CBC128,	"BATON-CBC128", NULL },
7113       { CKM_BATON_COUNTER,	"BATON-COUNTER", NULL },
7114       { CKM_BATON_SHUFFLE,	"BATON-SHUFFLE", NULL },
7115       { CKM_BATON_WRAP,		"BATON-WRAP", NULL },
7116       { CKM_ECDSA_KEY_PAIR_GEN,	"ECDSA-KEY-PAIR-GEN", NULL },
7117       { CKM_ECDSA,		"ECDSA", NULL },
7118       { CKM_ECDSA_SHA1,		"ECDSA-SHA1", NULL },
7119       { CKM_ECDSA_SHA224,	"ECDSA-SHA224", NULL },
7120       { CKM_ECDSA_SHA256,	"ECDSA-SHA256", NULL },
7121       { CKM_ECDSA_SHA384,	"ECDSA-SHA384", NULL },
7122       { CKM_ECDSA_SHA512,	"ECDSA-SHA512", NULL },
7123       { CKM_ECDH1_DERIVE,	"ECDH1-DERIVE", NULL },
7124       { CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL },
7125       { CKM_ECMQV_DERIVE,	"ECMQV-DERIVE", NULL },
7126       { CKM_EC_EDWARDS_KEY_PAIR_GEN,"EC-EDWARDS-KEY-PAIR-GEN", NULL },
7127       { CKM_EC_MONTGOMERY_KEY_PAIR_GEN,"EC-MONTGOMERY-KEY-PAIR-GEN", NULL },
7128       { CKM_EDDSA,		"EDDSA", NULL },
7129       { CKM_XEDDSA,		"XEDDSA", NULL },
7130       { CKM_JUNIPER_KEY_GEN,	"JUNIPER-KEY-GEN", NULL },
7131       { CKM_JUNIPER_ECB128,	"JUNIPER-ECB128", NULL },
7132       { CKM_JUNIPER_CBC128,	"JUNIPER-CBC128", NULL },
7133       { CKM_JUNIPER_COUNTER,	"JUNIPER-COUNTER", NULL },
7134       { CKM_JUNIPER_SHUFFLE,	"JUNIPER-SHUFFLE", NULL },
7135       { CKM_JUNIPER_WRAP,	"JUNIPER-WRAP", NULL },
7136       { CKM_FASTHASH,		"FASTHASH", NULL },
7137       { CKM_AES_KEY_GEN,	"AES-KEY-GEN", NULL },
7138       { CKM_AES_ECB,		"AES-ECB", NULL },
7139       { CKM_AES_CBC,		"AES-CBC", NULL },
7140       { CKM_AES_MAC,		"AES-MAC", NULL },
7141       { CKM_AES_MAC_GENERAL,	"AES-MAC-GENERAL", NULL },
7142       { CKM_AES_CBC_PAD,	"AES-CBC-PAD", NULL },
7143       { CKM_AES_CTR,		"AES-CTR", NULL },
7144       { CKM_AES_GCM,		"AES-GCM", NULL },
7145       { CKM_AES_CMAC,		"AES-CMAC", NULL },
7146       { CKM_DES_ECB_ENCRYPT_DATA, "DES-ECB-ENCRYPT-DATA", NULL },
7147       { CKM_DES_CBC_ENCRYPT_DATA, "DES-CBC-ENCRYPT-DATA", NULL },
7148       { CKM_DES3_ECB_ENCRYPT_DATA, "DES3-ECB-ENCRYPT-DATA", NULL },
7149       { CKM_DES3_CBC_ENCRYPT_DATA, "DES3-CBC-ENCRYPT-DATA", NULL },
7150       { CKM_AES_ECB_ENCRYPT_DATA, "AES-ECB-ENCRYPT-DATA", NULL },
7151       { CKM_AES_CBC_ENCRYPT_DATA, "AES-CBC-ENCRYPT-DATA", NULL },
7152       { CKM_GOST28147_KEY_GEN,	"GOST28147-KEY-GEN", NULL },
7153       { CKM_GOST28147_ECB,	"GOST28147-ECB", NULL },
7154       { CKM_GOST28147,	"GOST28147", NULL },
7155       { CKM_GOST28147_MAC,	"GOST28147-MAC", NULL },
7156       { CKM_GOST28147_KEY_WRAP,	"GOST28147-KEY-WRAP", NULL },
7157       { CKM_GOSTR3410_KEY_PAIR_GEN,"GOSTR3410-KEY-PAIR-GEN", NULL },
7158       { CKM_GOSTR3410,		"GOSTR3410", NULL },
7159       { CKM_GOSTR3410_DERIVE,	"GOSTR3410-DERIVE", NULL },
7160       { CKM_GOSTR3410_WITH_GOSTR3411,"GOSTR3410-WITH-GOSTR3411", NULL },
7161       { CKM_GOSTR3410_512_KEY_PAIR_GEN,	"GOSTR3410-512-KEY-PAIR-GEN", NULL },
7162       { CKM_GOSTR3410_512,	"GOSTR3410_512", NULL },
7163       { CKM_GOSTR3410_12_DERIVE,	"GOSTR3410-12-DERIVE", NULL },
7164       { CKM_GOSTR3410_WITH_GOSTR3411_12_256,	"GOSTR3410-WITH-GOSTR3411-12-256", NULL },
7165       { CKM_GOSTR3410_WITH_GOSTR3411_12_512,	"GOSTR3410-WITH-GOSTR3411-12-512", NULL },
7166       { CKM_GOSTR3411,		"GOSTR3411", NULL },
7167       { CKM_GOSTR3411_HMAC,	"GOSTR3411-HMAC", NULL },
7168       { CKM_GOSTR3411_12_256,	"GOSTR3411-12-256", NULL },
7169       { CKM_GOSTR3411_12_512,	"GOSTR3411-12-512", NULL },
7170       { CKM_GOSTR3411_12_256_HMAC,	"GOSTR3411-12-256-HMAC", NULL },
7171       { CKM_GOSTR3411_12_512_HMAC,	"GOSTR3411-12-512-HMAC", NULL },
7172       { CKM_DSA_PARAMETER_GEN,	"DSA-PARAMETER-GEN", NULL },
7173       { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL },
7174       { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL },
7175       { CKM_AES_KEY_WRAP,	"AES-KEY-WRAP", NULL},
7176       { 0, NULL, NULL }
7177 };
7178 
7179 static struct mech_info	p11_mgf[] = {
7180       { CKG_MGF1_SHA1,		"MGF1-SHA1", NULL },
7181       { CKG_MGF1_SHA224,	"MGF1-SHA224", NULL },
7182       { CKG_MGF1_SHA256,	"MGF1-SHA256", NULL },
7183       { CKG_MGF1_SHA384,	"MGF1-SHA384", NULL },
7184       { CKG_MGF1_SHA512,	"MGF1-SHA512", NULL },
7185       { 0, NULL, NULL }
7186 };
7187 
p11_mechanism_to_name(CK_MECHANISM_TYPE mech)7188 static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech)
7189 {
7190 	static char temp[64];
7191 	struct mech_info *mi;
7192 
7193 	for (mi = p11_mechanisms; mi->name; mi++) {
7194 		if (mi->mech == mech)
7195 			return mi->name;
7196 	}
7197 	snprintf(temp, sizeof(temp), "mechtype-0x%lX", (unsigned long) mech);
7198 	return temp;
7199 }
7200 
p11_name_to_mechanism(const char * name)7201 static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name)
7202 {
7203 	struct mech_info *mi;
7204 
7205 	if (strncasecmp("0x", name, 2) == 0) {
7206 		return strtoul(name, NULL, 0);
7207 	}
7208 	for (mi = p11_mechanisms; mi->name; mi++) {
7209 		if (!strcasecmp(mi->name, name)
7210 		 || (mi->short_name && !strcasecmp(mi->short_name, name)))
7211 			return mi->mech;
7212 	}
7213 	util_fatal("Unknown PKCS11 mechanism \"%s\"", name);
7214 	return 0; /* gcc food */
7215 }
7216 
p11_name_to_mgf(const char * name)7217 static CK_RSA_PKCS_MGF_TYPE p11_name_to_mgf(const char *name)
7218 {
7219 	struct mech_info *mi;
7220 
7221 	for (mi = p11_mgf; mi->name; mi++) {
7222 		if (!strcasecmp(mi->name, name))
7223 			return mi->mech;
7224 	}
7225 	util_fatal("Unknown PKCS11 MGF \"%s\"", name);
7226 }
7227 
p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf)7228 static const char *p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf)
7229 {
7230 	static char temp[64];
7231 	struct mech_info *mi;
7232 
7233 	for (mi = p11_mgf; mi->name; mi++) {
7234 		if (mi->mech == mgf)
7235 			return mi->name;
7236 	}
7237 	snprintf(temp, sizeof(temp), "mgf-0x%lX", (unsigned long) mgf);
7238 	return temp;
7239 }
7240 
CKR2Str(CK_ULONG res)7241 static const char * CKR2Str(CK_ULONG res)
7242 {
7243 	switch (res) {
7244 	case CKR_OK:
7245 		return "CKR_OK";
7246 	case CKR_CANCEL:
7247 		return "CKR_CANCEL";
7248 	case CKR_HOST_MEMORY:
7249 		return "CKR_HOST_MEMORY";
7250 	case CKR_SLOT_ID_INVALID:
7251 		return "CKR_SLOT_ID_INVALID";
7252 	case CKR_GENERAL_ERROR:
7253 		return "CKR_GENERAL_ERROR";
7254 	case CKR_FUNCTION_FAILED:
7255 		return "CKR_FUNCTION_FAILED";
7256 	case CKR_ARGUMENTS_BAD:
7257 		return "CKR_ARGUMENTS_BAD";
7258 	case CKR_NO_EVENT:
7259 		return "CKR_NO_EVENT";
7260 	case CKR_NEED_TO_CREATE_THREADS:
7261 		return "CKR_NEED_TO_CREATE_THREADS";
7262 	case CKR_CANT_LOCK:
7263 		return "CKR_CANT_LOCK";
7264 	case CKR_ATTRIBUTE_READ_ONLY:
7265 		return "CKR_ATTRIBUTE_READ_ONLY";
7266 	case CKR_ATTRIBUTE_SENSITIVE:
7267 		return "CKR_ATTRIBUTE_SENSITIVE";
7268 	case CKR_ATTRIBUTE_TYPE_INVALID:
7269 		return "CKR_ATTRIBUTE_TYPE_INVALID";
7270 	case CKR_ATTRIBUTE_VALUE_INVALID:
7271 		return "CKR_ATTRIBUTE_VALUE_INVALID";
7272 	case CKR_DATA_INVALID:
7273 		return "CKR_DATA_INVALID";
7274 	case CKR_DATA_LEN_RANGE:
7275 		return "CKR_DATA_LEN_RANGE";
7276 	case CKR_DEVICE_ERROR:
7277 		return "CKR_DEVICE_ERROR";
7278 	case CKR_DEVICE_MEMORY:
7279 		return "CKR_DEVICE_MEMORY";
7280 	case CKR_DEVICE_REMOVED:
7281 		return "CKR_DEVICE_REMOVED";
7282 	case CKR_ENCRYPTED_DATA_INVALID:
7283 		return "CKR_ENCRYPTED_DATA_INVALID";
7284 	case CKR_ENCRYPTED_DATA_LEN_RANGE:
7285 		return "CKR_ENCRYPTED_DATA_LEN_RANGE";
7286 	case CKR_FUNCTION_CANCELED:
7287 		return "CKR_FUNCTION_CANCELED";
7288 	case CKR_FUNCTION_NOT_PARALLEL:
7289 		return "CKR_FUNCTION_NOT_PARALLEL";
7290 	case CKR_FUNCTION_NOT_SUPPORTED:
7291 		return "CKR_FUNCTION_NOT_SUPPORTED";
7292 	case CKR_KEY_HANDLE_INVALID:
7293 		return "CKR_KEY_HANDLE_INVALID";
7294 	case CKR_KEY_SIZE_RANGE:
7295 		return "CKR_KEY_SIZE_RANGE";
7296 	case CKR_KEY_TYPE_INCONSISTENT:
7297 		return "CKR_KEY_TYPE_INCONSISTENT";
7298 	case CKR_KEY_NOT_NEEDED:
7299 		return "CKR_KEY_NOT_NEEDED";
7300 	case CKR_KEY_CHANGED:
7301 		return "CKR_KEY_CHANGED";
7302 	case CKR_KEY_NEEDED:
7303 		return "CKR_KEY_NEEDED";
7304 	case CKR_KEY_INDIGESTIBLE:
7305 		return "CKR_KEY_INDIGESTIBLE";
7306 	case CKR_KEY_FUNCTION_NOT_PERMITTED:
7307 		return "CKR_KEY_FUNCTION_NOT_PERMITTED";
7308 	case CKR_KEY_NOT_WRAPPABLE:
7309 		return "CKR_KEY_NOT_WRAPPABLE";
7310 	case CKR_KEY_UNEXTRACTABLE:
7311 		return "CKR_KEY_UNEXTRACTABLE";
7312 	case CKR_MECHANISM_INVALID:
7313 		return "CKR_MECHANISM_INVALID";
7314 	case CKR_MECHANISM_PARAM_INVALID:
7315 		return "CKR_MECHANISM_PARAM_INVALID";
7316 	case CKR_OBJECT_HANDLE_INVALID:
7317 		return "CKR_OBJECT_HANDLE_INVALID";
7318 	case CKR_OPERATION_ACTIVE:
7319 		return "CKR_OPERATION_ACTIVE";
7320 	case CKR_OPERATION_NOT_INITIALIZED:
7321 		return "CKR_OPERATION_NOT_INITIALIZED";
7322 	case CKR_PIN_INCORRECT:
7323 		return "CKR_PIN_INCORRECT";
7324 	case CKR_PIN_INVALID:
7325 		return "CKR_PIN_INVALID";
7326 	case CKR_PIN_LEN_RANGE:
7327 		return "CKR_PIN_LEN_RANGE";
7328 	case CKR_PIN_EXPIRED:
7329 		return "CKR_PIN_EXPIRED";
7330 	case CKR_PIN_LOCKED:
7331 		return "CKR_PIN_LOCKED";
7332 	case CKR_SESSION_CLOSED:
7333 		return "CKR_SESSION_CLOSED";
7334 	case CKR_SESSION_COUNT:
7335 		return "CKR_SESSION_COUNT";
7336 	case CKR_SESSION_HANDLE_INVALID:
7337 		return "CKR_SESSION_HANDLE_INVALID";
7338 	case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
7339 		return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
7340 	case CKR_SESSION_READ_ONLY:
7341 		return "CKR_SESSION_READ_ONLY";
7342 	case CKR_SESSION_EXISTS:
7343 		return "CKR_SESSION_EXISTS";
7344 	case CKR_SESSION_READ_ONLY_EXISTS:
7345 		return "CKR_SESSION_READ_ONLY_EXISTS";
7346 	case CKR_SESSION_READ_WRITE_SO_EXISTS:
7347 		return "CKR_SESSION_READ_WRITE_SO_EXISTS";
7348 	case CKR_SIGNATURE_INVALID:
7349 		return "CKR_SIGNATURE_INVALID";
7350 	case CKR_SIGNATURE_LEN_RANGE:
7351 		return "CKR_SIGNATURE_LEN_RANGE";
7352 	case CKR_TEMPLATE_INCOMPLETE:
7353 		return "CKR_TEMPLATE_INCOMPLETE";
7354 	case CKR_TEMPLATE_INCONSISTENT:
7355 		return "CKR_TEMPLATE_INCONSISTENT";
7356 	case CKR_TOKEN_NOT_PRESENT:
7357 		return "CKR_TOKEN_NOT_PRESENT";
7358 	case CKR_TOKEN_NOT_RECOGNIZED:
7359 		return "CKR_TOKEN_NOT_RECOGNIZED";
7360 	case CKR_TOKEN_WRITE_PROTECTED:
7361 		return "CKR_TOKEN_WRITE_PROTECTED";
7362 	case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
7363 		return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
7364 	case CKR_UNWRAPPING_KEY_SIZE_RANGE:
7365 		return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
7366 	case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
7367 		return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
7368 	case CKR_USER_ALREADY_LOGGED_IN:
7369 		return "CKR_USER_ALREADY_LOGGED_IN";
7370 	case CKR_USER_NOT_LOGGED_IN:
7371 		return "CKR_USER_NOT_LOGGED_IN";
7372 	case CKR_USER_PIN_NOT_INITIALIZED:
7373 		return "CKR_USER_PIN_NOT_INITIALIZED";
7374 	case CKR_USER_TYPE_INVALID:
7375 		return "CKR_USER_TYPE_INVALID";
7376 	case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
7377 		return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
7378 	case CKR_USER_TOO_MANY_TYPES:
7379 		return "CKR_USER_TOO_MANY_TYPES";
7380 	case CKR_WRAPPED_KEY_INVALID:
7381 		return "CKR_WRAPPED_KEY_INVALID";
7382 	case CKR_WRAPPED_KEY_LEN_RANGE:
7383 		return "CKR_WRAPPED_KEY_LEN_RANGE";
7384 	case CKR_WRAPPING_KEY_HANDLE_INVALID:
7385 		return "CKR_WRAPPING_KEY_HANDLE_INVALID";
7386 	case CKR_WRAPPING_KEY_SIZE_RANGE:
7387 		return "CKR_WRAPPING_KEY_SIZE_RANGE";
7388 	case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
7389 		return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
7390 	case CKR_RANDOM_SEED_NOT_SUPPORTED:
7391 		return "CKR_RANDOM_SEED_NOT_SUPPORTED";
7392 	case CKR_RANDOM_NO_RNG:
7393 		return "CKR_RANDOM_NO_RNG";
7394 	case CKR_DOMAIN_PARAMS_INVALID:
7395 		return "CKR_DOMAIN_PARAMS_INVALID";
7396 	case CKR_BUFFER_TOO_SMALL:
7397 		return "CKR_BUFFER_TOO_SMALL";
7398 	case CKR_SAVED_STATE_INVALID:
7399 		return "CKR_SAVED_STATE_INVALID";
7400 	case CKR_INFORMATION_SENSITIVE:
7401 		return "CKR_INFORMATION_SENSITIVE";
7402 	case CKR_STATE_UNSAVEABLE:
7403 		return "CKR_STATE_UNSAVEABLE";
7404 	case CKR_CRYPTOKI_NOT_INITIALIZED:
7405 		return "CKR_CRYPTOKI_NOT_INITIALIZED";
7406 	case CKR_CRYPTOKI_ALREADY_INITIALIZED:
7407 		return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
7408 	case CKR_MUTEX_BAD:
7409 		return "CKR_MUTEX_BAD";
7410 	case CKR_MUTEX_NOT_LOCKED:
7411 		return "CKR_MUTEX_NOT_LOCKED";
7412 	case CKR_VENDOR_DEFINED:
7413 		return "CKR_VENDOR_DEFINED";
7414 	}
7415 	return "unknown PKCS11 error";
7416 }
7417 
7418 #if defined(_WIN32) || defined(HAVE_PTHREAD)
7419 #ifdef _WIN32
test_threads_run(_In_ LPVOID pttd)7420 static DWORD WINAPI test_threads_run(_In_ LPVOID pttd)
7421 #else
7422 static void * test_threads_run(void * pttd)
7423 #endif
7424 {
7425 	int r = 0;
7426 	CK_RV rv = CKR_OK;
7427 	CK_INFO info;
7428 	int l_slots = 0;
7429 	int state = 0;
7430 	CK_ULONG l_p11_num_slots = 0;
7431 	CK_SLOT_ID_PTR l_p11_slots = NULL;
7432 	char * pctest;
7433 	struct test_threads_data * ttd = (struct test_threads_data *)pttd;
7434 
7435 	fprintf(stderr, "Test thread %d started with options:%s\n", ttd->tnum, ttd->tests);
7436 	/* call selected C_* routines with different options */
7437 	pctest = ttd-> tests;
7438 
7439 	/* series of two chatacter commands */
7440 	while (pctest && *pctest && *(pctest + 1)) {
7441 		ttd->state = state++;
7442 
7443 		/*  Pn - pause where n is 0 to 9 iseconds */
7444 		if (*pctest == 'P' && *(pctest + 1) >= '0' && *(pctest + 1) <= '9') {
7445 			fprintf(stderr, "Test thread %d pauseing for %d seconds\n", ttd->tnum, (*(pctest + 1) - '0'));
7446 #ifdef _WIN32
7447 			Sleep((*(pctest + 1) - '0') * 1000);
7448 #else
7449 			sleep(*(pctest + 1) - '0');
7450 #endif
7451 		}
7452 
7453 		/* IN - C_Initialize with NULL args */
7454 		else if (*pctest == 'I') {
7455 			if (*(pctest + 1) == 'N') {
7456 				fprintf(stderr, "Test thread %d C_Initialize(NULL)\n", ttd->tnum);
7457 				rv = p11->C_Initialize(NULL);
7458 				ttd->rv = rv;
7459 				fprintf(stderr, "Test thread %d C_Initialize returned %s\n", ttd->tnum, CKR2Str(rv));
7460 			}
7461 			/* CL C_Initialize with CKF_OS_LOCKING_OK */
7462 			else if (*(pctest + 1) == 'L') {
7463 				fprintf(stderr, "Test thread %d C_Initialize CKF_OS_LOCKING_OK \n", ttd->tnum);
7464 				rv = p11->C_Initialize(&c_initialize_args_OS);
7465 				ttd->rv = rv;
7466 				fprintf(stderr, "Test thread %d C_Initialize  returned %s\n", ttd->tnum, CKR2Str(rv));
7467 			}
7468 			else
7469 				goto err;
7470 		}
7471 
7472 		/* GI - C_GetInfo */
7473 		else if (*pctest == 'G' && *(pctest + 1) == 'I') {
7474 			fprintf(stderr, "Test thread %d C_GetInfo\n", ttd->tnum);
7475 			rv = p11->C_GetInfo(&info);
7476 			ttd->rv = rv;
7477 			fprintf(stderr, "Test thread %d C_GetInfo returned %s\n", ttd->tnum, CKR2Str(rv));
7478 		}
7479 
7480 		/* SL - C_GetSlotList */
7481 		else if (*pctest == 'S' && *(pctest + 1) == 'L') {
7482 			fprintf(stderr, "Test thread %d C_GetSlotList to get l_p11_num_slots\n", ttd->tnum);
7483 			rv = p11->C_GetSlotList(1, NULL, &l_p11_num_slots);
7484 			ttd->rv = rv;
7485 			fprintf(stderr, "Test thread %d C_GetSlotList returned %s\n", ttd->tnum, CKR2Str(rv));
7486 			fprintf(stderr, "Test thread %d l_p11_num_slots:%ld\n", ttd->tnum, l_p11_num_slots);
7487 			if (rv == CKR_OK) {
7488 				free(l_p11_slots);
7489 				l_p11_slots = NULL;
7490 				if (l_p11_num_slots > 0) {
7491 					l_p11_slots = calloc(l_p11_num_slots, sizeof(CK_SLOT_ID));
7492 					if (l_p11_slots == NULL) {
7493 						goto err;
7494 					}
7495 					fprintf(stderr, "Test thread %d C_GetSlotList\n", ttd->tnum);
7496 					rv = p11->C_GetSlotList(1, l_p11_slots, &l_p11_num_slots);
7497 					ttd->rv = rv;
7498 					fprintf(stderr, "Test thread %d C_GetSlotList returned %s\n", ttd->tnum, CKR2Str(rv));
7499 					fprintf(stderr, "Test thread %d l_p11_num_slots:%ld\n", ttd->tnum, l_p11_num_slots);
7500 					if (rv == CKR_OK && l_p11_num_slots && l_p11_slots)
7501 						l_slots = 1;
7502 				}
7503 			}
7504 		}
7505 
7506 		/* Tn Get token from slot_index n C_GetTokenInfo, where n is 0 to 9 */
7507 		else if (*pctest == 'T' && *(pctest + 1) >= '0' && *(pctest + 1) <= '9') {
7508 			fprintf(stderr, "Test thread %d C_GetTokenInfo from slot_index %d using show_token\n", ttd->tnum, (*(pctest + 1) - '0'));
7509 			if (l_slots) {
7510 				show_token(l_p11_slots[(*(pctest + 1) - '0')]);
7511 			} else {
7512 				show_token(p11_slots[(*(pctest + 1) - '0')]);
7513 			}
7514 		}
7515 
7516 		else {
7517 		err:
7518 			rv = CKR_GENERAL_ERROR; /* could be vendor error, */
7519 			ttd->rv = rv;
7520 			fprintf(stderr, "Test thread %d Unknown test '%c%c'\n", ttd->tnum, *pctest, *(pctest + 1));
7521 			break;
7522 		}
7523 
7524 		pctest ++;
7525 		if (*pctest != 0x00)
7526 			pctest ++;
7527 		if (*pctest == ':')
7528 			pctest++;
7529 
7530 
7531 		if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)
7532 		/* IN C_Initialize with NULL args */
7533 			break;
7534 	}
7535 
7536 	free(l_p11_slots);
7537 	fprintf(stderr, "Test thread %d returning rv = %d\n", ttd->tnum, r);
7538 	ttd->state = -1; /* done */
7539 	ttd->rv = rv;
7540 #ifdef _WIN32
7541 	ExitThread(0);
7542 #else
7543 	pthread_exit(NULL);
7544 #endif
7545 }
7546 
test_threads_cleanup()7547 static int test_threads_cleanup()
7548 {
7549 
7550 	int i, j;
7551 	int ended = 0;
7552 	int ended_ok = 0;
7553 
7554 	fprintf(stderr,"test_threads cleanup starting\n");
7555 	for (j = 0; j < 4; j++) {
7556 		ended = 0;
7557 		ended_ok = 0;
7558 
7559 		for (i = 0; i < test_threads_num; i++) {
7560 			if (test_threads_datas[i].state == -1) {
7561 				ended++;
7562 			}
7563 			if (test_threads_datas[i].rv == CKR_OK) {
7564 				ended_ok++;
7565 			}
7566 		}
7567 
7568 		if (ended == test_threads_num) {
7569 			fprintf(stderr,"test_threads all threads have ended %s\n",
7570 					(ended_ok == test_threads_num)? "with CKR_OK": "some errors");
7571 			break;
7572 		} else {
7573 			fprintf(stderr,"test_threads threads stills active:%d\n", (test_threads_num - ended));
7574 			for (i = 0; i < test_threads_num; i++) {
7575 				fprintf(stderr,"test_threads thread:%d state:%d, rv:%s\n",
7576 					i, test_threads_datas[i].state, CKR2Str(test_threads_datas[i].rv));
7577 			}
7578 			fprintf(stderr,"\ntest_threads waiting for 30 seconds ...\n");
7579 #ifdef _WIN32
7580 			Sleep(30*1000);
7581 #else
7582 			sleep(30);
7583 #endif
7584 		}
7585 	}
7586 
7587 	for (i = 0; i < test_threads_num; i++) {
7588 		fprintf(stderr,"test_threads thread:%d state:%d, rv:%s\n",
7589 			i, test_threads_datas[i].state, CKR2Str(test_threads_datas[i].rv));
7590 		if (test_threads_datas[i].state == -1) {
7591 #ifdef _WIN32
7592 			TerminateThread(test_threads_handles[i], 0);
7593 #else
7594 			pthread_join(test_threads_handles[i], NULL);
7595 		} else {
7596 			pthread_cancel(test_threads_handles[i]);
7597 #endif
7598 		}
7599 	}
7600 
7601 	fprintf(stderr,"test_threads cleanup finished\n");
7602 	return 0;
7603 }
7604 
test_threads_start(int tnum)7605 static int test_threads_start(int tnum)
7606 {
7607 	int r = 0;
7608 
7609 #ifdef _WIN32
7610 	test_threads_handles[tnum] = CreateThread(NULL, 0, test_threads_run, (LPVOID) &test_threads_datas[tnum],
7611 		0, NULL);
7612 	if (test_threads_handles[tnum] == NULL) {
7613 		r = GetLastError();
7614 	}
7615 #else
7616 	pthread_attr_t attr;
7617 	pthread_attr_init(&attr);
7618 	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
7619 	r = pthread_create(&test_threads_handles[tnum], &attr, test_threads_run, (void *) &test_threads_datas[tnum]);
7620 #endif
7621 	if (r != 0) {
7622 		fprintf(stderr,"test_threads pthread_create failed %d for thread %d\n", r, tnum);
7623 		/* system error */
7624 	}
7625 	return r;
7626 }
7627 
7628 /*********************************************************************************************/
test_threads()7629 static void test_threads()
7630 {
7631 	int  i;
7632 
7633 	/* call test_threads_start for each --test-thread option */
7634 
7635 	/* upon return, C_Initialize will be called, from main code */
7636 	for (i = 0; i < test_threads_num && i < MAX_TEST_THREADS; i++) {
7637 		test_threads_start(i);
7638 	}
7639 }
7640 #endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */
7641