hooray, pluto and scepclient do not depend on libgmp anymore
[strongswan.git] / src / pluto / smartcard.c
1 /* Support of smartcards and cryptotokens
2 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
3 * Copyright (C) 2004 David Buechi, Michael Meier
4 * Zuercher Hochschule Winterthur, Switzerland
5 *
6 * Copyright (C) 2005 Michael Joosten
7 *
8 * Copyright (C) 2005 Andreas Steffen
9 * Hochschule fuer Technik Rapperswil, Switzerland
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <time.h>
28 #include <dlfcn.h>
29
30 #include <freeswan.h>
31
32 #include <asn1/asn1.h>
33 #include <credentials/keys/public_key.h>
34
35 #include "constants.h"
36
37 #ifdef SMARTCARD
38 #include "rsaref/unix.h"
39 #include "rsaref/pkcs11.h"
40 #endif
41
42 #include "defs.h"
43 #include "log.h"
44 #include "x509.h"
45 #include "ca.h"
46 #include "certs.h"
47 #include "keys.h"
48 #include "smartcard.h"
49 #include "whack.h"
50 #include "fetch.h"
51
52 #define DEFAULT_BASE 16
53
54 /* chained list of smartcard records */
55 static smartcard_t *smartcards = NULL;
56
57 /* number of generated sc objects */
58 static int sc_number = 0;
59
60 const smartcard_t empty_sc = {
61 NULL , /* next */
62 0 , /* last_load */
63 { CERT_NONE, {NULL} }, /* last_cert */
64 0 , /* count */
65 0 , /* number */
66 999999 , /* slot */
67 NULL , /* id */
68 NULL , /* label */
69 { NULL, 0 } , /* pin */
70 FALSE , /* pinpad */
71 FALSE , /* valid */
72 FALSE , /* session_opened */
73 FALSE , /* logged_in */
74 TRUE , /* any_slot */
75 0L , /* session */
76 };
77
78 #ifdef SMARTCARD /* compile with smartcard support */
79
80 #define SCX_MAGIC 0xd00bed00
81
82 struct scx_pkcs11_module {
83 u_int _magic;
84 void *handle;
85 };
86
87 typedef struct scx_pkcs11_module scx_pkcs11_module_t;
88
89 /* PKCS #11 cryptoki context */
90 static bool scx_initialized = FALSE;
91 static scx_pkcs11_module_t *pkcs11_module = NULL_PTR;
92 static CK_FUNCTION_LIST_PTR pkcs11_functions = NULL_PTR;
93
94 /* crytoki v2.11 - return values of PKCS #11 functions*/
95
96 static const char *const pkcs11_return_name[] = {
97 "CKR_OK",
98 "CKR_CANCEL",
99 "CKR_HOST_MEMORY",
100 "CKR_SLOT_ID_INVALID",
101 "CKR_FLAGS_INVALID",
102 "CKR_GENERAL_ERROR",
103 "CKR_FUNCTION_FAILED",
104 "CKR_ARGUMENTS_BAD",
105 "CKR_NO_EVENT",
106 "CKR_NEED_TO_CREATE_THREADS",
107 "CKR_CANT_LOCK"
108 };
109
110 static const char *const pkcs11_return_name_10[] = {
111 "CKR_ATTRIBUTE_READ_ONLY",
112 "CKR_ATTRIBUTE_SENSITIVE",
113 "CKR_ATTRIBUTE_TYPE_INVALID",
114 "CKR_ATTRIBUTE_VALUE_INVALID"
115 };
116
117 static const char *const pkcs11_return_name_20[] = {
118 "CKR_DATA_INVALID",
119 "CKR_DATA_LEN_RANGE"
120 };
121
122 static const char *const pkcs11_return_name_30[] = {
123 "CKR_DEVICE_ERROR",
124 "CKR_DEVICE_MEMORY",
125 "CKR_DEVICE_REMOVED"
126 };
127
128 static const char *const pkcs11_return_name_40[] = {
129 "CKR_ENCRYPTED_DATA_INVALID",
130 "CKR_ENCRYPTED_DATA_LEN_RANGE"
131 };
132
133 static const char *const pkcs11_return_name_50[] = {
134 "CKR_FUNCTION_CANCELED",
135 "CKR_FUNCTION_NOT_PARALLEL",
136 "CKR_0x52_UNDEFINED",
137 "CKR_0x53_UNDEFINED",
138 "CKR_FUNCTION_NOT_SUPPORTED"
139 };
140
141 static const char *const pkcs11_return_name_60[] = {
142 "CKR_KEY_HANDLE_INVALID",
143 "CKR_KEY_SENSITIVE",
144 "CKR_KEY_SIZE_RANGE",
145 "CKR_KEY_TYPE_INCONSISTENT",
146 "CKR_KEY_NOT_NEEDED",
147 "CKR_KEY_CHANGED",
148 "CKR_KEY_NEEDED",
149 "CKR_KEY_INDIGESTIBLE",
150 "CKR_KEY_FUNCTION_NOT_PERMITTED",
151 "CKR_KEY_NOT_WRAPPABLE",
152 "CKR_KEY_UNEXTRACTABLE"
153 };
154
155 static const char *const pkcs11_return_name_70[] = {
156 "CKR_MECHANISM_INVALID",
157 "CKR_MECHANISM_PARAM_INVALID"
158 };
159
160 static const char *const pkcs11_return_name_80[] = {
161 "CKR_OBJECT_HANDLE_INVALID"
162 };
163
164 static const char *const pkcs11_return_name_90[] = {
165 "CKR_OPERATION_ACTIVE",
166 "CKR_OPERATION_NOT_INITIALIZED"
167 };
168
169 static const char *const pkcs11_return_name_A0[] = {
170 "CKR_PIN_INCORRECT",
171 "CKR_PIN_INVALID",
172 "CKR_PIN_LEN_RANGE",
173 "CKR_PIN_EXPIRED",
174 "CKR_PIN_LOCKED"
175 };
176
177 static const char *const pkcs11_return_name_B0[] = {
178 "CKR_SESSION_CLOSED",
179 "CKR_SESSION_COUNT",
180 "CKR_0xB2_UNDEFINED",
181 "CKR_SESSION_HANDLE_INVALID",
182 "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
183 "CKR_SESSION_READ_ONLY",
184 "CKR_SESSION_EXISTS",
185 "CKR_SESSION_READ_ONLY_EXISTS",
186 "CKR_SESSION_READ_WRITE_SO_EXISTS"
187 };
188
189 static const char *const pkcs11_return_name_C0[] = {
190 "CKR_SIGNATURE_INVALID",
191 "CKR_SIGNATURE_LEN_RANGE"
192 };
193
194 static const char *const pkcs11_return_name_D0[] = {
195 "CKR_TEMPLATE_INCOMPLETE",
196 "CKR_TEMPLATE_INCONSISTENT"
197 };
198
199 static const char *const pkcs11_return_name_E0[] = {
200 "CKR_TOKEN_NOT_PRESENT",
201 "CKR_TOKEN_NOT_RECOGNIZED",
202 "CKR_TOKEN_WRITE_PROTECTED"
203 };
204
205 static const char *const pkcs11_return_name_F0[] = {
206 "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
207 "CKR_UNWRAPPING_KEY_SIZE_RANGE",
208 "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"
209 };
210
211 static const char *const pkcs11_return_name_100[] = {
212 "CKR_USER_ALREADY_LOGGED_IN",
213 "CKR_USER_NOT_LOGGED_IN",
214 "CKR_USER_PIN_NOT_INITIALIZED",
215 "CKR_USER_TYPE_INVALID",
216 "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
217 "CKR_USER_TOO_MANY_TYPES"
218 };
219
220 static const char *const pkcs11_return_name_110[] = {
221 "CKR_WRAPPED_KEY_INVALID",
222 "CKR_0x111_UNDEFINED",
223 "CKR_WRAPPED_KEY_LEN_RANGE",
224 "CKR_WRAPPING_KEY_HANDLE_INVALID",
225 "CKR_WRAPPING_KEY_SIZE_RANGE",
226 "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"
227 };
228
229 static const char *const pkcs11_return_name_120[] = {
230 "CKR_RANDOM_SEED_NOT_SUPPORTED",
231 "CKR_RANDOM_NO_RNG"
232 };
233
234 static const char *const pkcs11_return_name_130[] = {
235 "CKR_DOMAIN_PARAMS_INVALID"
236 };
237
238 static const char *const pkcs11_return_name_150[] = {
239 "CKR_BUFFER_TOO_SMALL"
240 };
241
242 static const char *const pkcs11_return_name_160[] = {
243 "CKR_SAVED_STATE_INVALID"
244 };
245
246 static const char *const pkcs11_return_name_170[] = {
247 "CKR_INFORMATION_SENSITIVE"
248 };
249
250 static const char *const pkcs11_return_name_180[] = {
251 "CKR_STATE_UNSAVEABLE"
252 };
253
254 static const char *const pkcs11_return_name_190[] = {
255 "CKR_CRYPTOKI_NOT_INITIALIZED",
256 "CKR_CRYPTOKI_ALREADY_INITIALIZED"
257 };
258
259 static const char *const pkcs11_return_name_1A0[] = {
260 "CKR_MUTEX_BAD",
261 "CKR_MUTEX_NOT_LOCKED"
262 };
263
264 static const char *const pkcs11_return_name_200[] = {
265 "CKR_FUNCTION_REJECTED"
266 };
267
268 static const char *const pkcs11_return_name_vendor[] = {
269 "CKR_VENDOR_DEFINED"
270 };
271
272 static enum_names pkcs11_return_names_vendor =
273 { CKR_VENDOR_DEFINED, CKR_VENDOR_DEFINED
274 , pkcs11_return_name_vendor, NULL };
275
276 static enum_names pkcs11_return_names_200 =
277 { CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED
278 , pkcs11_return_name_200, &pkcs11_return_names_vendor };
279
280 static enum_names pkcs11_return_names_1A0 =
281 { CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED
282 , pkcs11_return_name_1A0, &pkcs11_return_names_200 };
283
284 static enum_names pkcs11_return_names_190 =
285 { CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED
286 , pkcs11_return_name_190, &pkcs11_return_names_1A0 };
287
288 static enum_names pkcs11_return_names_180 =
289 { CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE
290 , pkcs11_return_name_180, &pkcs11_return_names_190 };
291
292 static enum_names pkcs11_return_names_170 =
293 { CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE
294 , pkcs11_return_name_170, &pkcs11_return_names_180 };
295
296 static enum_names pkcs11_return_names_160 =
297 { CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID
298 , pkcs11_return_name_160, &pkcs11_return_names_170 };
299
300 static enum_names pkcs11_return_names_150 =
301 { CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL
302 , pkcs11_return_name_150, &pkcs11_return_names_160 };
303
304 static enum_names pkcs11_return_names_130 =
305 { CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID
306 , pkcs11_return_name_130, &pkcs11_return_names_150 };
307
308 static enum_names pkcs11_return_names_120 =
309 { CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG
310 , pkcs11_return_name_120, &pkcs11_return_names_130 };
311
312 static enum_names pkcs11_return_names_110 =
313 { CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT
314 , pkcs11_return_name_110, &pkcs11_return_names_120 };
315
316 static enum_names pkcs11_return_names_100 =
317 { CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES
318 , pkcs11_return_name_100, &pkcs11_return_names_110 };
319
320 static enum_names pkcs11_return_names_F0 =
321 { CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
322 , pkcs11_return_name_F0, &pkcs11_return_names_100 };
323
324 static enum_names pkcs11_return_names_E0 =
325 { CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED
326 , pkcs11_return_name_E0, &pkcs11_return_names_F0 };
327
328 static enum_names pkcs11_return_names_D0 =
329 { CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT
330 , pkcs11_return_name_D0,&pkcs11_return_names_E0 };
331
332 static enum_names pkcs11_return_names_C0 =
333 { CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE
334 , pkcs11_return_name_C0, &pkcs11_return_names_D0 };
335
336 static enum_names pkcs11_return_names_B0 =
337 { CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS
338 , pkcs11_return_name_B0, &pkcs11_return_names_C0 };
339
340 static enum_names pkcs11_return_names_A0 =
341 { CKR_PIN_INCORRECT, CKR_PIN_LOCKED
342 , pkcs11_return_name_A0, &pkcs11_return_names_B0 };
343
344 static enum_names pkcs11_return_names_90 =
345 { CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED
346 , pkcs11_return_name_90, &pkcs11_return_names_A0 };
347
348 static enum_names pkcs11_return_names_80 =
349 { CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID
350 , pkcs11_return_name_80, &pkcs11_return_names_90 };
351
352 static enum_names pkcs11_return_names_70 =
353 { CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID
354 , pkcs11_return_name_70, &pkcs11_return_names_80 };
355
356 static enum_names pkcs11_return_names_60 =
357 { CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE
358 , pkcs11_return_name_60, &pkcs11_return_names_70 };
359
360 static enum_names pkcs11_return_names_50 =
361 { CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED
362 , pkcs11_return_name_50, &pkcs11_return_names_60 };
363
364 static enum_names pkcs11_return_names_40 =
365 { CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE
366 , pkcs11_return_name_40, &pkcs11_return_names_50 };
367
368 static enum_names pkcs11_return_names_30 =
369 { CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED
370 , pkcs11_return_name_30, &pkcs11_return_names_40 };
371
372 static enum_names pkcs11_return_names_20 =
373 { CKR_DATA_INVALID, CKR_DATA_LEN_RANGE
374 , pkcs11_return_name_20, &pkcs11_return_names_30 };
375
376 static enum_names pkcs11_return_names_10 =
377 { CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID
378 , pkcs11_return_name_10, &pkcs11_return_names_20};
379
380 static enum_names pkcs11_return_names =
381 { CKR_OK, CKR_CANT_LOCK
382 , pkcs11_return_name, &pkcs11_return_names_10};
383
384 /*
385 * Unload a PKCS#11 module.
386 * The calling application is responsible for cleaning up
387 * and calling C_Finalize()
388 */
389 static CK_RV
390 scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
391 {
392 if (!mod || mod->_magic != SCX_MAGIC)
393 return CKR_ARGUMENTS_BAD;
394
395 if (dlclose(mod->handle) < 0)
396 return CKR_FUNCTION_FAILED;
397
398 memset(mod, 0, sizeof(*mod));
399 free(mod);
400 return CKR_OK;
401 }
402
403 static scx_pkcs11_module_t*
404 scx_load_pkcs11_module(const char *name, CK_FUNCTION_LIST_PTR_PTR funcs)
405 {
406 CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
407 scx_pkcs11_module_t *mod;
408 void *handle;
409 int rv;
410
411 if (name == NULL || *name == '\0')
412 return NULL;
413
414 /* Try to load PKCS#11 library module*/
415 handle = dlopen(name, RTLD_NOW);
416 if (handle == NULL)
417 return NULL;
418
419 mod = malloc_thing(scx_pkcs11_module_t);
420 mod->_magic = SCX_MAGIC;
421 mod->handle = handle;
422
423 /* Get the list of function pointers */
424 c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
425 dlsym(mod->handle, "C_GetFunctionList");
426 if (!c_get_function_list)
427 goto failed;
428
429 rv = c_get_function_list(funcs);
430 if (rv == CKR_OK)
431 return mod;
432
433 failed: scx_unload_pkcs11_module(mod);
434 return NULL;
435 }
436
437 /*
438 * retrieve a certificate object
439 */
440 static bool
441 scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
442 , smartcard_t *sc, cert_t *cert)
443 {
444 size_t hex_len, label_len;
445 u_char *hex_id = NULL;
446 chunk_t blob;
447 x509cert_t *x509cert;
448
449 CK_ATTRIBUTE attr[] = {
450 { CKA_ID, NULL_PTR, 0L },
451 { CKA_LABEL, NULL_PTR, 0L },
452 { CKA_VALUE, NULL_PTR, 0L }
453 };
454
455 /* initialize the return argument */
456 *cert = cert_empty;
457
458 /* get the length of the attributes first */
459 CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
460 if (rv != CKR_OK)
461 {
462 plog("couldn't read the attribute sizes: %s"
463 , enum_show(&pkcs11_return_names, rv));
464 return FALSE;
465 }
466
467 free(sc->label);
468
469 hex_id = malloc(attr[0].ulValueLen);
470 hex_len = attr[0].ulValueLen;
471 sc->label = malloc(attr[1].ulValueLen + 1);
472 label_len = attr[1].ulValueLen;
473 blob.ptr = malloc(attr[2].ulValueLen);
474 blob.len = attr[2].ulValueLen;
475
476 attr[0].pValue = hex_id;
477 attr[1].pValue = sc->label;
478 attr[2].pValue = blob.ptr;
479
480 /* now get the attributes */
481 rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
482 if (rv != CKR_OK)
483 {
484 plog("couldn't read the attributes: %s"
485 , enum_show(&pkcs11_return_names, rv));
486 free(hex_id);
487 free(sc->label);
488 free(blob.ptr);
489 return FALSE;
490 }
491
492 free(sc->id);
493
494 /* convert id from hex to ASCII */
495 sc->id = malloc(2*hex_len + 1);
496 datatot(hex_id, hex_len, 16, sc->id, 2*hex_len + 1);
497 free(hex_id);
498
499 /* safeguard in case the label is not null terminated */
500 sc->label[label_len] = '\0';
501
502 /* parse the retrieved cert */
503 x509cert = malloc_thing(x509cert_t);
504 *x509cert = empty_x509cert;
505 x509cert->smartcard = TRUE;
506
507 if (!parse_x509cert(blob, 0, x509cert))
508 {
509 plog("failed to load cert from smartcard, error in X.509 certificate");
510 free_x509cert(x509cert);
511 return FALSE;
512 }
513 cert->type = CERT_X509_SIGNATURE;
514 cert->u.x509 = x509cert;
515 return TRUE;
516 }
517
518 /*
519 * search a given slot for PKCS#11 certificate objects
520 */
521 static void
522 scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
523 {
524 CK_RV rv;
525 CK_OBJECT_CLASS class = CKO_CERTIFICATE;
526 CK_ATTRIBUTE attr[] = {{ CKA_CLASS, &class, sizeof(class) }};
527
528 rv = pkcs11_functions->C_FindObjectsInit(session, attr, 1);
529 if (rv != CKR_OK)
530 {
531 plog("error in C_FindObjectsInit: %s"
532 , enum_show(&pkcs11_return_names, rv));
533 return;
534 }
535
536 for (;;)
537 {
538 CK_OBJECT_HANDLE object;
539 CK_ULONG obj_count = 0;
540 err_t ugh;
541 time_t valid_until;
542 smartcard_t *sc;
543 x509cert_t *cert;
544
545 rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
546 if (rv != CKR_OK)
547 {
548 plog("error in C_FindObjects: %s"
549 , enum_show(&pkcs11_return_names, rv));
550 break;
551 }
552
553 /* no objects left */
554 if (obj_count == 0)
555 break;
556
557 /* create and initialize a new smartcard object */
558 sc = malloc_thing(smartcard_t);
559 *sc = empty_sc;
560 sc->any_slot = FALSE;
561 sc->slot = slot;
562
563 if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
564 {
565 scx_free(sc);
566 continue;
567 }
568 DBG(DBG_CONTROL,
569 DBG_log("found cert in %s with id: %s, label: '%s'"
570 , scx_print_slot(sc, ""), sc->id, sc->label)
571 )
572
573 /* check validity of certificate */
574 cert = sc->last_cert.u.x509;
575 valid_until = cert->notAfter;
576 ugh = check_validity(cert, &valid_until);
577 if (ugh != NULL)
578 {
579 plog(" %s", ugh);
580 free_x509cert(cert);
581 scx_free(sc);
582 continue;
583 }
584 else
585 {
586 DBG(DBG_CONTROL,
587 DBG_log(" certificate is valid")
588 )
589 }
590
591 sc = scx_add(sc);
592
593 /* put end entity and ca certificates into different chains */
594 if (cert->isCA)
595 {
596 sc->last_cert.u.x509 = add_authcert(cert, AUTH_CA);
597 }
598 else
599 {
600 add_x509_public_key(cert, valid_until, DAL_LOCAL);
601 sc->last_cert.u.x509 = add_x509cert(cert);
602 }
603
604 share_cert(sc->last_cert);
605 time(&sc->last_load);
606 }
607
608 rv = pkcs11_functions->C_FindObjectsFinal(session);
609 if (rv != CKR_OK)
610 {
611 plog("error in C_FindObjectsFinal: %s"
612 , enum_show(&pkcs11_return_names, rv));
613 }
614 }
615
616 /*
617 * search all slots for PKCS#11 certificate objects
618 */
619 static void
620 scx_find_all_cert_objects(void)
621 {
622 CK_RV rv;
623 CK_SLOT_ID_PTR slots = NULL_PTR;
624 CK_ULONG slot_count = 0;
625 CK_ULONG i;
626
627 if (!scx_initialized)
628 {
629 plog("pkcs11 module not initialized");
630 return;
631 }
632
633 /* read size, always returns CKR_OK ! */
634 rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
635
636 /* allocate memory for the slots */
637 slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
638
639 rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
640 if (rv != CKR_OK)
641 {
642 plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
643 free(slots);
644 return;
645 }
646
647 /* look in every slot for certificate objects */
648 for (i = 0; i < slot_count; i++)
649 {
650 CK_SLOT_ID slot = slots[i];
651 CK_SLOT_INFO info;
652 CK_SESSION_HANDLE session;
653
654 rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
655
656 if (rv != CKR_OK)
657 {
658 plog("error in C_GetSlotInfo: %s"
659 , enum_show(&pkcs11_return_names, rv));
660 continue;
661 }
662
663 if (!(info.flags & CKF_TOKEN_PRESENT))
664 {
665 plog("no token present in slot %lu", slot);
666 continue;
667 }
668
669 rv = pkcs11_functions->C_OpenSession(slot
670 , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
671 if (rv != CKR_OK)
672 {
673 plog("failed to open a session on slot %lu: %s"
674 , slot, enum_show(&pkcs11_return_names, rv));
675 continue;
676 }
677 DBG(DBG_CONTROLMORE,
678 DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
679 )
680 scx_find_cert_objects(slot, session);
681
682 rv = pkcs11_functions->C_CloseSession(session);
683 if (rv != CKR_OK)
684 {
685 plog("error in C_CloseSession: %s"
686 , enum_show(&pkcs11_return_names, rv));
687 }
688 }
689 free(slots);
690 }
691 #endif
692
693 /*
694 * load and initialize PKCS#11 cryptoki module
695 *
696 * init_args should be unused when we have a PKCS#11 compliant module,
697 * but NSS softoken breaks that API.
698 */
699 void
700 scx_init(const char* module, const char *init_args)
701 {
702 #ifdef SMARTCARD
703 CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
704 CK_RV rv;
705
706 if (scx_initialized)
707 {
708 plog("weird - pkcs11 module seems already to be initialized");
709 return;
710 }
711
712 if (module == NULL)
713 #ifdef PKCS11_DEFAULT_LIB
714 module = PKCS11_DEFAULT_LIB;
715 #else
716 {
717 plog("no pkcs11 module defined");
718 return;
719 }
720 #endif
721
722 DBG(DBG_CONTROL | DBG_CRYPT,
723 DBG_log("pkcs11 module '%s' loading...", module)
724 )
725 pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
726 if (pkcs11_module == NULL)
727 {
728 plog("failed to load pkcs11 module '%s'", module);
729 return;
730 }
731
732 DBG(DBG_CONTROL | DBG_CRYPT,
733 DBG_log("pkcs11 module initializing...")
734 )
735 rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
736 if (rv != CKR_OK)
737 {
738 plog("failed to initialize pkcs11 module: %s"
739 , enum_show(&pkcs11_return_names, rv));
740 return;
741 }
742
743 scx_initialized = TRUE;
744 DBG(DBG_CONTROL | DBG_CRYPT,
745 DBG_log("pkcs11 module loaded and initialized")
746 )
747
748 scx_find_all_cert_objects();
749 #endif
750 }
751
752 /*
753 * finalize and unload PKCS#11 cryptoki module
754 */
755 void
756 scx_finalize(void)
757 {
758 #ifdef SMARTCARD
759 while (smartcards != NULL)
760 {
761 scx_release(smartcards);
762 }
763
764 if (pkcs11_functions != NULL_PTR)
765 {
766 pkcs11_functions->C_Finalize(NULL_PTR);
767 pkcs11_functions = NULL_PTR;
768 }
769
770 if (pkcs11_module != NULL)
771 {
772 scx_unload_pkcs11_module(pkcs11_module);
773 pkcs11_module = NULL;
774 }
775
776 scx_initialized = FALSE;
777 DBG(DBG_CONTROL | DBG_CRYPT,
778 DBG_log("pkcs11 module finalized and unloaded")
779 )
780 #endif
781 }
782
783 /*
784 * does a filename contain the token %smartcard?
785 */
786 bool
787 scx_on_smartcard(const char *filename)
788 {
789 return strneq(filename, SCX_TOKEN, strlen(SCX_TOKEN));
790 }
791
792 #ifdef SMARTCARD
793 /*
794 * find a specific object on the smartcard
795 */
796 static bool
797 scx_pkcs11_find_object( CK_SESSION_HANDLE session,
798 CK_OBJECT_HANDLE_PTR object,
799 CK_OBJECT_CLASS class,
800 const char* id)
801 {
802 size_t len;
803 char buf[BUF_LEN];
804 CK_RV rv;
805 CK_ULONG obj_count = 0;
806 CK_ULONG attr_count = 1;
807
808 CK_ATTRIBUTE attr[] = {
809 { CKA_CLASS, &class, sizeof(class) },
810 { CKA_ID, &buf, 0L }
811 };
812
813 if (id != NULL)
814 {
815 ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
816 attr[1].ulValueLen = len;
817 attr_count = 2;
818 }
819
820 /* get info for certificate with id */
821 rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
822 if (rv != CKR_OK)
823 {
824 plog("error in C_FindObjectsInit: %s"
825 , enum_show(&pkcs11_return_names, rv));
826 return FALSE;
827 }
828
829 rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
830 if (rv != CKR_OK)
831 {
832 plog("error in C_FindObjects: %s"
833 , enum_show(&pkcs11_return_names, rv));
834 return FALSE;
835 }
836
837 rv = pkcs11_functions->C_FindObjectsFinal(session);
838 if (rv != CKR_OK)
839 {
840 plog("error in C_FindObjectsFinal: %s"
841 , enum_show(&pkcs11_return_names, rv));
842 return FALSE;
843 }
844
845 return (obj_count != 0);
846 }
847
848 /*
849 * check if a given certificate object id is found in a slot
850 */
851 static bool
852 scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
853 {
854 CK_SESSION_HANDLE session;
855 CK_OBJECT_HANDLE object;
856 CK_SLOT_INFO info;
857
858 CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
859
860 if (rv != CKR_OK)
861 {
862 plog("error in C_GetSlotInfo: %s"
863 , enum_show(&pkcs11_return_names, rv));
864 return FALSE;
865 }
866
867 if (!(info.flags & CKF_TOKEN_PRESENT))
868 {
869 plog("no token present in slot %lu", slot);
870 return FALSE;
871 }
872
873 rv = pkcs11_functions->C_OpenSession(slot
874 , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
875 if (rv != CKR_OK)
876 {
877 plog("failed to open a session on slot %lu: %s"
878 , slot, enum_show(&pkcs11_return_names, rv));
879 return FALSE;
880 }
881 DBG(DBG_CONTROLMORE,
882 DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
883 )
884
885 /* check if there is a certificate on the card in the specified slot */
886 if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
887 {
888 sc->slot = slot;
889 sc->any_slot = FALSE;
890 sc->session = session;
891 sc->session_opened = TRUE;
892 return TRUE;
893 }
894
895 rv = pkcs11_functions->C_CloseSession(session);
896 if (rv != CKR_OK)
897 {
898 plog("error in C_CloseSession: %s"
899 , enum_show(&pkcs11_return_names, rv));
900 }
901 return FALSE;
902 }
903 #endif
904
905 /*
906 * Connect to the smart card in the reader and select the correct slot
907 */
908 bool
909 scx_establish_context(smartcard_t *sc)
910 {
911 #ifdef SMARTCARD
912 bool id_found = FALSE;
913
914 if (!scx_initialized)
915 {
916 plog("pkcs11 module not initialized");
917 return FALSE;
918 }
919
920 if (sc->session_opened)
921 {
922 DBG(DBG_CONTROL | DBG_CRYPT,
923 DBG_log("pkcs11 session #%ld already open", sc->session)
924 )
925 return TRUE;
926 }
927
928 if (!sc->any_slot)
929 id_found = scx_find_cert_id_in_slot(sc, sc->slot);
930
931 if (!id_found)
932 {
933 CK_RV rv;
934 CK_SLOT_ID slot;
935 CK_SLOT_ID_PTR slots = NULL_PTR;
936 CK_ULONG slot_count = 0;
937 CK_ULONG i;
938
939 /* read size, always returns CKR_OK ! */
940 rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
941
942 /* allocate memory for the slots */
943 slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
944
945 rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
946 if (rv != CKR_OK)
947 {
948 plog("error in C_GetSlotList: %s"
949 , enum_show(&pkcs11_return_names, rv));
950 free(slots);
951 return FALSE;
952 }
953
954 /* look in every slot for a certificate with a given object ID */
955 for (i = 0; i < slot_count; i++)
956 {
957 slot = slots[i];
958 id_found = scx_find_cert_id_in_slot(sc, slot);
959 if (id_found)
960 break;
961 }
962 free(slots);
963 }
964
965 if (id_found)
966 {
967 DBG(DBG_CONTROL | DBG_CRYPT,
968 DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
969 DBG_log("pkcs11 session #%ld opened", sc->session)
970 )
971 }
972 else
973 {
974 plog(" no certificate with id %s found on smartcard", sc->id);
975 }
976 return id_found;
977 #else
978 plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
979 return FALSE;
980 #endif
981 }
982
983 /*
984 * log in to a session
985 */
986 bool
987 scx_login(smartcard_t *sc)
988 {
989 #ifdef SMARTCARD
990 CK_RV rv;
991
992 if (sc->logged_in)
993 {
994 DBG(DBG_CONTROL | DBG_CRYPT,
995 DBG_log("pkcs11 session #%ld login already done", sc->session)
996 )
997 return TRUE;
998 }
999
1000 if (sc->pin.ptr == NULL)
1001 {
1002 plog("unable to log in without PIN!");
1003 return FALSE;
1004 }
1005
1006 if (!sc->session_opened)
1007 {
1008 plog("session not opened");
1009 return FALSE;
1010 }
1011
1012 rv = pkcs11_functions->C_Login(sc->session, CKU_USER
1013 , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1014 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
1015 {
1016 plog("unable to login: %s"
1017 , enum_show(&pkcs11_return_names, rv));
1018 return FALSE;
1019 }
1020 DBG(DBG_CONTROL | DBG_CRYPT,
1021 DBG_log("pkcs11 session #%ld login successful", sc->session)
1022 )
1023 sc->logged_in = TRUE;
1024 return TRUE;
1025 #else
1026 return FALSE;
1027 #endif
1028 }
1029
1030 #ifdef SMARTCARD
1031 /*
1032 * logout from a session
1033 */
1034 static void
1035 scx_logout(smartcard_t *sc)
1036 {
1037 CK_RV rv;
1038
1039 rv = pkcs11_functions->C_Logout(sc->session);
1040 if (rv != CKR_OK)
1041 plog("error in C_Logout: %s"
1042 , enum_show(&pkcs11_return_names, rv));
1043 else
1044 DBG(DBG_CONTROL | DBG_CRYPT,
1045 DBG_log("pkcs11 session #%ld logout", sc->session)
1046 )
1047 sc->logged_in = FALSE;
1048 }
1049 #endif
1050
1051
1052 /*
1053 * Release context and disconnect from card
1054 */
1055 void
1056 scx_release_context(smartcard_t *sc)
1057 {
1058 #ifdef SMARTCARD
1059 CK_RV rv;
1060
1061 if (!scx_initialized)
1062 return;
1063
1064 if (sc->session_opened)
1065 {
1066 if (sc->logged_in)
1067 scx_logout(sc);
1068
1069 sc->session_opened = FALSE;
1070
1071 rv = pkcs11_functions->C_CloseSession(sc->session);
1072 if (rv != CKR_OK)
1073 plog("error in C_CloseSession: %s"
1074 , enum_show(&pkcs11_return_names, rv));
1075 else
1076 DBG(DBG_CONTROL | DBG_CRYPT,
1077 DBG_log("pkcs11 session #%ld closed", sc->session)
1078 )
1079 }
1080 #endif
1081 }
1082
1083 /*
1084 * Load host certificate from smartcard
1085 */
1086 bool
1087 scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
1088 , bool *cached)
1089 {
1090 #ifdef SMARTCARD /* compile with smartcard support */
1091 CK_OBJECT_HANDLE object;
1092
1093 const char *number_slot_id = filename + strlen(SCX_TOKEN);
1094
1095 smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
1096
1097 /* return the smartcard object */
1098 *scp = sc;
1099
1100 /* is there a cached smartcard certificate? */
1101 *cached = sc->last_cert.type != CERT_NONE
1102 && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
1103
1104 if (*cached)
1105 {
1106 *cert = sc->last_cert;
1107 plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
1108 , sc->number
1109 , scx_print_slot(sc, "")
1110 , sc->id
1111 , sc->label);
1112 return TRUE;
1113 }
1114
1115 if (!scx_establish_context(sc))
1116 {
1117 scx_release_context(sc);
1118 return FALSE;
1119 }
1120
1121 /* find the certificate object */
1122 if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
1123 {
1124 scx_release_context(sc);
1125 return FALSE;
1126 }
1127
1128 /* retrieve the certificate object */
1129 if (!scx_find_cert_object(sc->session, object, sc, cert))
1130 {
1131 scx_release_context(sc);
1132 return FALSE;
1133 }
1134
1135 if (!pkcs11_keep_state)
1136 scx_release_context(sc);
1137
1138 plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
1139 , sc->number
1140 , scx_print_slot(sc, "")
1141 , sc->id
1142 , sc->label);
1143
1144 return TRUE;
1145 #else
1146 plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
1147 return FALSE;
1148 #endif
1149 }
1150
1151 /*
1152 * parse slot number and key id
1153 * the following syntax is allowed
1154 * number slot id
1155 * %smartcard 1 - -
1156 * %smartcard#2 2 - -
1157 * %smartcard0 - 0 -
1158 * %smartcard:45 - - 45
1159 * %smartcard0:45 - 0 45
1160 */
1161 smartcard_t*
1162 scx_parse_number_slot_id(const char *number_slot_id)
1163 {
1164 int len = strlen(number_slot_id);
1165 smartcard_t *sc = malloc_thing(smartcard_t);
1166
1167 /* assign default values */
1168 *sc = empty_sc;
1169
1170 if (len == 0) /* default: use certificate #1 */
1171 {
1172 sc->number = 1;
1173 }
1174 else if (*number_slot_id == '#') /* #number scheme */
1175 {
1176 err_t ugh;
1177 unsigned long ul;
1178
1179 ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
1180 if (ugh == NULL)
1181 sc->number = (int)ul;
1182 else
1183 plog("error parsing smartcard number: %s", ugh);
1184 }
1185 else /* slot:id scheme */
1186 {
1187 int slot_len = len;
1188 char *p = strchr(number_slot_id, ':');
1189
1190 if (p != NULL)
1191 {
1192 int id_len = len - (p + 1 - number_slot_id);
1193 slot_len -= (1 + id_len);
1194
1195 if (id_len > 0) /* we have an id */
1196 sc->id = p + 1;
1197 }
1198 if (slot_len > 0) /* we have a slot */
1199 {
1200 err_t ugh = NULL;
1201 unsigned long ul;
1202
1203 ugh = atoul(number_slot_id, slot_len, 10, &ul);
1204 if (ugh == NULL)
1205 {
1206 sc->slot = ul;
1207 sc->any_slot = FALSE;
1208 }
1209 else
1210 plog("error parsing smartcard slot number: %s", ugh);
1211 }
1212 }
1213 /* unshare the id string */
1214 sc->id = clone_str(sc->id);
1215 return sc;
1216 }
1217
1218 /*
1219 * Verify pin on card
1220 */
1221 bool
1222 scx_verify_pin(smartcard_t *sc)
1223 {
1224 #ifdef SMARTCARD
1225 CK_RV rv;
1226
1227 if (!sc->pinpad)
1228 sc->valid = FALSE;
1229
1230 if (sc->pin.ptr == NULL)
1231 {
1232 plog("unable to verify without PIN");
1233 return FALSE;
1234 }
1235
1236 /* establish context */
1237 if (!scx_establish_context(sc))
1238 {
1239 scx_release_context(sc);
1240 return FALSE;
1241 }
1242
1243 rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
1244 (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1245 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
1246 {
1247 sc->valid = TRUE;
1248 sc->logged_in = TRUE;
1249 DBG(DBG_CONTROL | DBG_CRYPT,
1250 DBG_log((rv == CKR_OK)
1251 ? "PIN code correct"
1252 : "already logged in, no PIN entry required");
1253 DBG_log("pkcs11 session #%ld login successful", sc->session)
1254 )
1255 }
1256 else
1257 {
1258 DBG(DBG_CONTROL | DBG_CRYPT,
1259 DBG_log("PIN code incorrect")
1260 )
1261 }
1262 if (!pkcs11_keep_state)
1263 scx_release_context(sc);
1264 #else
1265 sc->valid = FALSE;
1266 #endif
1267 return sc->valid;
1268 }
1269
1270 /*
1271 * Sign hash on smartcard
1272 */
1273 bool
1274 scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
1275 , u_char *out, size_t outlen)
1276 {
1277 #ifdef SMARTCARD
1278 CK_RV rv;
1279 CK_OBJECT_HANDLE object;
1280 CK_ULONG siglen = (CK_ULONG)outlen;
1281 CK_BBOOL sign_flag, decrypt_flag;
1282 CK_ATTRIBUTE attr[] = {
1283 { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
1284 { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
1285 };
1286
1287 if (!sc->logged_in)
1288 return FALSE;
1289
1290 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1291 {
1292 plog("unable to find private key with id '%s'", sc->id);
1293 return FALSE;
1294 }
1295
1296 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1297 if (rv != CKR_OK)
1298 {
1299 plog("couldn't read the private key attributes: %s"
1300 , enum_show(&pkcs11_return_names, rv));
1301 return FALSE;
1302 }
1303 DBG(DBG_CONTROL,
1304 DBG_log("RSA key flags: sign = %s, decrypt = %s"
1305 , (sign_flag)? "true":"false"
1306 , (decrypt_flag)? "true":"false")
1307 )
1308
1309 if (sign_flag)
1310 {
1311 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1312
1313 rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
1314 if (rv != CKR_OK)
1315 {
1316 plog("error in C_SignInit: %s"
1317 , enum_show(&pkcs11_return_names, rv));
1318 return FALSE;
1319 }
1320
1321 rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
1322 , out, &siglen);
1323 if (rv != CKR_OK)
1324 {
1325 plog("error in C_Sign: %s"
1326 , enum_show(&pkcs11_return_names, rv));
1327 return FALSE;
1328 }
1329 }
1330 else if (decrypt_flag)
1331 {
1332 CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
1333 size_t padlen;
1334 u_char *p = out ;
1335
1336 /* PKCS#1 v1.5 8.1 encryption-block formatting */
1337 *p++ = 0x00;
1338 *p++ = 0x01; /* BT (block type) 01 */
1339 padlen = outlen - 3 - inlen;
1340 memset(p, 0xFF, padlen);
1341 p += padlen;
1342 *p++ = 0x00;
1343 memcpy(p, in, inlen);
1344
1345 rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
1346 if (rv != CKR_OK)
1347 {
1348 plog("error in C_DecryptInit: %s"
1349 , enum_show(&pkcs11_return_names, rv));
1350 return FALSE;
1351 }
1352
1353 rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
1354 , out, &siglen);
1355 if (rv != CKR_OK)
1356 {
1357 plog("error in C_Decrypt: %s"
1358 , enum_show(&pkcs11_return_names, rv));
1359 return FALSE;
1360 }
1361 }
1362 else
1363 {
1364 plog("private key has neither sign nor decrypt flag set");
1365 return FALSE;
1366 }
1367
1368 if (siglen > (CK_ULONG)outlen)
1369 {
1370 plog("signature length (%lu) larger than allocated buffer (%d)"
1371 , siglen, (int)outlen);
1372 return FALSE;
1373 }
1374 return TRUE;
1375 #else
1376 return FALSE;
1377 #endif
1378 }
1379
1380 /*
1381 * encrypt data block with an RSA public key
1382 */
1383 bool
1384 scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
1385 , u_char *out, size_t *outlen)
1386 {
1387 #ifdef SMARTCARD
1388 CK_RV rv;
1389 CK_OBJECT_HANDLE object;
1390 CK_ULONG len = (CK_ULONG)(*outlen);
1391 CK_BBOOL encrypt_flag;
1392 CK_ATTRIBUTE attr[] = {
1393 { CKA_MODULUS, NULL_PTR, 0L },
1394 { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
1395 { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
1396 };
1397 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1398
1399 if (!scx_establish_context(sc))
1400 {
1401 scx_release_context(sc);
1402 return FALSE;
1403 }
1404
1405 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
1406 {
1407 plog("unable to find public key with id '%s'", sc->id);
1408 return FALSE;
1409 }
1410
1411 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
1412 if (rv != CKR_OK)
1413 {
1414 plog("couldn't read the public key attributes: %s"
1415 , enum_show(&pkcs11_return_names, rv));
1416 scx_release_context(sc);
1417 return FALSE;
1418 }
1419
1420 if (!encrypt_flag)
1421 {
1422 plog("public key cannot be used for encryption");
1423 scx_release_context(sc);
1424 return FALSE;
1425 }
1426
1427 /* there must be enough space left for the PKCS#1 v1.5 padding */
1428 if (inlen > attr[0].ulValueLen - 11)
1429 {
1430 plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
1431 , (int)inlen, attr[0].ulValueLen - 11);
1432 if (!pkcs11_keep_state)
1433 scx_release_context(sc);
1434 return FALSE;
1435 }
1436
1437 rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
1438
1439 if (rv != CKR_OK)
1440 {
1441 if (rv == CKR_FUNCTION_NOT_SUPPORTED)
1442 {
1443 public_key_t *key;
1444 chunk_t rsa_modulus, rsa_exponent, rsa_key, cipher_text;
1445 chunk_t plain_text = {(u_char*)in, inlen};
1446
1447 DBG(DBG_CONTROL,
1448 DBG_log("doing RSA encryption in software")
1449 )
1450 attr[0].pValue = malloc(attr[0].ulValueLen);
1451 attr[1].pValue = malloc(attr[1].ulValueLen);
1452
1453 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1454 if (rv != CKR_OK)
1455 {
1456 plog("couldn't read modulus and public exponent: %s"
1457 , enum_show(&pkcs11_return_names, rv));
1458 free(attr[0].pValue);
1459 free(attr[1].pValue);
1460 scx_release_context(sc);
1461 return FALSE;
1462 }
1463 rsa_modulus = chunk_create((u_char*) attr[0].pValue,
1464 (size_t) attr[0].ulValueLen);
1465 rsa_exponent = chunk_create((u_char*) attr[1].pValue,
1466 (size_t) attr[1].ulValueLen);
1467 rsa_key = asn1_wrap(ASN1_SEQUENCE, "mm",
1468 asn1_integer("m", rsa_modulus),
1469 asn1_integer("m", rsa_exponent));
1470 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
1471 BUILD_BLOB_ASN1_DER, rsa_key, BUILD_END);
1472 free(rsa_key.ptr);
1473 if (key == NULL)
1474 {
1475 return FALSE;
1476 }
1477 key->encrypt(key, plain_text, &cipher_text);
1478 key->destroy(key);
1479
1480 if (cipher_text.ptr == NULL)
1481 {
1482 plog("smartcard input data length is too large");
1483 if (!pkcs11_keep_state)
1484 {
1485 scx_release_context(sc);
1486 }
1487 return FALSE;
1488 }
1489
1490 memcpy(out, cipher_text.ptr, cipher_text.len);
1491 *outlen = cipher_text.len;
1492 free(cipher_text.ptr);
1493
1494 if (!pkcs11_keep_state)
1495 {
1496 scx_release_context(sc);
1497 }
1498 return TRUE;
1499 }
1500 else
1501 {
1502 plog("error in C_EncryptInit: %s"
1503 , enum_show(&pkcs11_return_names, rv));
1504 scx_release_context(sc);
1505 return FALSE;
1506 }
1507 }
1508
1509 DBG(DBG_CONTROL,
1510 DBG_log("doing RSA encryption on smartcard")
1511 )
1512 rv = pkcs11_functions->C_Encrypt(sc->session, (u_char*)in, inlen
1513 , out, &len);
1514 if (rv != CKR_OK)
1515 {
1516 plog("error in C_Encrypt: %s"
1517 , enum_show(&pkcs11_return_names, rv));
1518 scx_release_context(sc);
1519 return FALSE;
1520 }
1521 if (!pkcs11_keep_state)
1522 scx_release_context(sc);
1523
1524 *outlen = (size_t)len;
1525 return TRUE;
1526 #else
1527 return FALSE;
1528 #endif
1529 }
1530 /*
1531 * decrypt a data block with an RSA private key
1532 */
1533 bool
1534 scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
1535 , u_char *out, size_t *outlen)
1536 {
1537 #ifdef SMARTCARD
1538 CK_RV rv;
1539 CK_OBJECT_HANDLE object;
1540 CK_ULONG len = (CK_ULONG)(*outlen);
1541 CK_BBOOL decrypt_flag;
1542 CK_ATTRIBUTE attr[] = {
1543 { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
1544 };
1545 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1546
1547 if (!scx_establish_context(sc) || !scx_login(sc))
1548 {
1549 scx_release_context(sc);
1550 return FALSE;
1551 }
1552
1553 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1554 {
1555 plog("unable to find private key with id '%s'", sc->id);
1556 return FALSE;
1557 }
1558
1559 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
1560 if (rv != CKR_OK)
1561 {
1562 plog("couldn't read the private key attributes: %s"
1563 , enum_show(&pkcs11_return_names, rv));
1564 return FALSE;
1565 }
1566
1567 if (!decrypt_flag)
1568 {
1569 plog("private key cannot be used for decryption");
1570 scx_release_context(sc);
1571 return FALSE;
1572 }
1573
1574 DBG(DBG_CONTROL,
1575 DBG_log("doing RSA decryption on smartcard")
1576 )
1577 rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
1578 if (rv != CKR_OK)
1579 {
1580 plog("error in C_DecryptInit: %s"
1581 , enum_show(&pkcs11_return_names, rv));
1582 scx_release_context(sc);
1583 return FALSE;
1584 }
1585
1586 rv = pkcs11_functions->C_Decrypt(sc->session, (u_char*)in, inlen
1587 , out, &len);
1588 if (rv != CKR_OK)
1589 {
1590 plog("error in C_Decrypt: %s"
1591 , enum_show(&pkcs11_return_names, rv));
1592 scx_release_context(sc);
1593 return FALSE;
1594 }
1595 if (!pkcs11_keep_state)
1596 scx_release_context(sc);
1597
1598 *outlen = (size_t)len;
1599 return TRUE;
1600 #else
1601 return FALSE;
1602 #endif
1603 }
1604
1605 /* receive an encrypted data block via whack,
1606 * decrypt it using a private RSA key and
1607 * return the decrypted data block via whack
1608 */
1609 bool
1610 scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
1611 , const char* keyid, int whackfd)
1612 {
1613 char inbuf[RSA_MAX_OCTETS];
1614 char outbuf[2*RSA_MAX_OCTETS + 1];
1615 size_t outlen = sizeof(inbuf);
1616 size_t inlen;
1617 smartcard_t *sc,*sc_new;
1618
1619 const char *number_slot_id = "";
1620
1621 err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
1622
1623 /* no prefix - use default base */
1624 if (ugh != NULL && inbase == 0)
1625 ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
1626
1627 if (ugh != NULL)
1628 {
1629 plog("format error in smartcard input data: %s", ugh);
1630 return FALSE;
1631 }
1632
1633 if (keyid != NULL)
1634 {
1635 number_slot_id = (strneq(keyid, SCX_TOKEN, strlen(SCX_TOKEN)))
1636 ? keyid + strlen(SCX_TOKEN) : keyid;
1637 }
1638
1639 sc_new = scx_parse_number_slot_id(number_slot_id);
1640 sc = scx_add(sc_new);
1641 if (sc == sc_new)
1642 scx_share(sc);
1643
1644 DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
1645 DBG_dump("smartcard input data:\n", inbuf, inlen)
1646 )
1647
1648 if (op == SC_OP_DECRYPT)
1649 {
1650 if (!sc->valid && whackfd != NULL_FD)
1651 scx_get_pin(sc, whackfd);
1652
1653 if (!sc->valid)
1654 {
1655 loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
1656 return FALSE;
1657 }
1658 }
1659
1660 DBG(DBG_CONTROL | DBG_CRYPT,
1661 DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
1662 , (int)sc->slot, sc->id)
1663 )
1664
1665 switch (op)
1666 {
1667 case SC_OP_ENCRYPT:
1668 if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
1669 return FALSE;
1670 break;
1671 case SC_OP_DECRYPT:
1672 if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
1673 return FALSE;
1674 break;
1675 default:
1676 break;
1677 }
1678
1679 DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
1680 DBG_dump("smartcard output data:\n", inbuf, outlen)
1681 )
1682
1683 if (outbase == 0) /* use default base */
1684 outbase = DEFAULT_BASE;
1685
1686 if (outbase == 256) /* ascii plain text */
1687 whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
1688 else
1689 {
1690 outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
1691 if (outlen == 0)
1692 {
1693 plog("error in output format conversion");
1694 return FALSE;
1695 }
1696 whack_log(RC_COMMENT, "%s", outbuf);
1697 }
1698 return TRUE;
1699 }
1700
1701 /*
1702 * get length of RSA key in bytes
1703 */
1704 size_t
1705 scx_get_keylength(smartcard_t *sc)
1706 {
1707 #ifdef SMARTCARD
1708 CK_RV rv;
1709 CK_OBJECT_HANDLE object;
1710 CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
1711
1712 if (!sc->logged_in)
1713 return FALSE;
1714
1715 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1716 {
1717 plog("unable to find private key with id '%s'", sc->id);
1718 return FALSE;
1719 }
1720
1721 /* get the length of the private key */
1722 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
1723 , (CK_ATTRIBUTE_PTR)&attr, 1);
1724 if (rv != CKR_OK)
1725 {
1726 plog("failed to get key length: %s"
1727 , enum_show(&pkcs11_return_names, rv));
1728 return FALSE;
1729 }
1730
1731 return attr[0].ulValueLen; /*Return key length in bytes */
1732 #else
1733 return 0;
1734 #endif
1735 }
1736
1737 /*
1738 * prompt for pin and verify it
1739 */
1740 bool
1741 scx_get_pin(smartcard_t *sc, int whackfd)
1742 {
1743 #ifdef SMARTCARD
1744 char pin[BUF_LEN];
1745 int i, n;
1746
1747 whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
1748 , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
1749
1750 for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
1751 {
1752 if (i > 0)
1753 whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
1754
1755 n = read(whackfd, pin, BUF_LEN);
1756
1757 if (n == -1)
1758 {
1759 whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
1760 return FALSE;
1761 }
1762
1763 if (strlen(pin) == 0)
1764 {
1765 whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
1766 return FALSE;
1767 }
1768
1769 sc->pin.ptr = pin;
1770 sc->pin.len = strlen(pin);
1771
1772 /* verify the pin */
1773 if (scx_verify_pin(sc))
1774 {
1775 sc->pin = chunk_create(pin, strlen(pin));
1776 sc->pin = chunk_clone(sc->pin);
1777 break;
1778 }
1779
1780 /* wrong pin - we try another round */
1781 sc->pin = chunk_empty;
1782 }
1783
1784 if (sc->valid)
1785 whack_log(RC_SUCCESS, "valid PIN");
1786 else
1787 whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
1788 #else
1789 sc->valid = FALSE;
1790 whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
1791 #endif
1792 return sc->valid;
1793 }
1794
1795
1796 /*
1797 * free the pin code
1798 */
1799 void
1800 scx_free_pin(chunk_t *pin)
1801 {
1802 if (pin->ptr != NULL)
1803 {
1804 /* clear pin field in memory */
1805 memset(pin->ptr, '\0', pin->len);
1806 free(pin->ptr);
1807 *pin = chunk_empty;
1808 }
1809 }
1810
1811 /*
1812 * frees a smartcard record
1813 */
1814 void
1815 scx_free(smartcard_t *sc)
1816 {
1817 if (sc != NULL)
1818 {
1819 scx_release_context(sc);
1820 free(sc->id);
1821 free(sc->label);
1822 scx_free_pin(&sc->pin);
1823 free(sc);
1824 }
1825 }
1826
1827 /* release of a smartcard record decreases the count by one
1828 " the record is freed when the counter reaches zero
1829 */
1830 void
1831 scx_release(smartcard_t *sc)
1832 {
1833 if (sc != NULL && --sc->count == 0)
1834 {
1835 smartcard_t **pp = &smartcards;
1836 while (*pp != sc)
1837 pp = &(*pp)->next;
1838 *pp = sc->next;
1839 release_cert(sc->last_cert);
1840 scx_free(sc);
1841 }
1842 }
1843
1844 /*
1845 * compare two smartcard records by comparing their slots and ids
1846 */
1847 static bool
1848 scx_same(smartcard_t *a, smartcard_t *b)
1849 {
1850 if (a->number && b->number)
1851 {
1852 /* same number */
1853 return a->number == b->number;
1854 }
1855 else
1856 {
1857 /* same id and/or same slot */
1858 return (!a->id || (b->id && streq(a->id, b->id)))
1859 && (a->any_slot || b->any_slot || a->slot == b->slot);
1860 }
1861 }
1862
1863 /* for each link pointing to the smartcard record
1864 " increase the count by one
1865 */
1866 void
1867 scx_share(smartcard_t *sc)
1868 {
1869 if (sc != NULL)
1870 sc->count++;
1871 }
1872
1873 /*
1874 * adds a smartcard record to the chained list
1875 */
1876 smartcard_t*
1877 scx_add(smartcard_t *smartcard)
1878 {
1879 smartcard_t *sc = smartcards;
1880 smartcard_t **psc = &smartcards;
1881
1882 while (sc != NULL)
1883 {
1884 if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
1885 {
1886 scx_free(smartcard);
1887 return sc;
1888 }
1889 psc = &sc->next;
1890 sc = sc->next;
1891 }
1892
1893 /* insert new smartcard record at the end of the chain */
1894 *psc = smartcard;
1895 smartcard->number = ++sc_number;
1896 smartcard->count = 1;
1897 DBG(DBG_CONTROL | DBG_PARSING,
1898 DBG_log(" smartcard #%d added", sc_number)
1899 )
1900 return smartcard;
1901 }
1902
1903 /*
1904 * get the smartcard that belongs to an X.509 certificate
1905 */
1906 smartcard_t*
1907 scx_get(x509cert_t *cert)
1908 {
1909 smartcard_t *sc = smartcards;
1910
1911 while (sc != NULL)
1912 {
1913 if (sc->last_cert.u.x509 == cert)
1914 return sc;
1915 sc = sc->next;
1916 }
1917 return NULL;
1918 }
1919
1920 /*
1921 * prints either the slot number or 'any slot'
1922 */
1923 char *
1924 scx_print_slot(smartcard_t *sc, const char *whitespace)
1925 {
1926 char *buf = temporary_cyclic_buffer();
1927
1928 if (sc->any_slot)
1929 snprintf(buf, BUF_LEN, "any slot");
1930 else
1931 snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
1932 return buf;
1933 }
1934
1935 /*
1936 * list all smartcard info records in a chained list
1937 */
1938 void
1939 scx_list(bool utc)
1940 {
1941 smartcard_t *sc = smartcards;
1942
1943 if (sc != NULL)
1944 {
1945 whack_log(RC_COMMENT, " ");
1946 whack_log(RC_COMMENT, "List of Smartcard Objects:");
1947 whack_log(RC_COMMENT, " ");
1948 }
1949
1950 while (sc != NULL)
1951 {
1952 whack_log(RC_COMMENT, "%T, #%d, count: %d"
1953 , &sc->last_load, utc
1954 , sc->number
1955 , sc->count);
1956 whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
1957 , scx_print_slot(sc, " ")
1958 , sc->session_opened? "opened" : "closed"
1959 , sc->logged_in? "in" : "out"
1960 , sc->pinpad? "pin pad"
1961 : ((sc->pin.ptr == NULL)? "no pin"
1962 : sc->valid? "valid pin" : "invalid pin"));
1963 if (sc->id != NULL)
1964 whack_log(RC_COMMENT, " id: %s", sc->id);
1965 if (sc->label != NULL)
1966 whack_log(RC_COMMENT, " label: '%s'", sc->label);
1967 if (sc->last_cert.type == CERT_X509_SIGNATURE)
1968 {
1969 char buf[BUF_LEN];
1970
1971 dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
1972 whack_log(RC_COMMENT, " subject: '%s'", buf);
1973 }
1974 sc = sc->next;
1975 }
1976 }