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