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