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