fixed bug occuring with multiple occurences of the same cacert on a smartcard
[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 {
597 sc->last_cert.u.x509 = add_authcert(cert, AUTH_CA);
598 }
599 else
600 {
601 add_x509_public_key(cert, valid_until, DAL_LOCAL);
602 sc->last_cert.u.x509 = add_x509cert(cert);
603 }
604
605 share_cert(sc->last_cert);
606 time(&sc->last_load);
607 }
608
609 rv = pkcs11_functions->C_FindObjectsFinal(session);
610 if (rv != CKR_OK)
611 {
612 plog("error in C_FindObjectsFinal: %s"
613 , enum_show(&pkcs11_return_names, rv));
614 }
615 }
616
617 /*
618 * search all slots for PKCS#11 certificate objects
619 */
620 static void
621 scx_find_all_cert_objects(void)
622 {
623 CK_RV rv;
624 CK_SLOT_ID_PTR slots = NULL_PTR;
625 CK_ULONG slot_count = 0;
626 CK_ULONG i;
627
628 if (!scx_initialized)
629 {
630 plog("pkcs11 module not initialized");
631 return;
632 }
633
634 /* read size, always returns CKR_OK ! */
635 rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
636
637 /* allocate memory for the slots */
638 slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
639
640 rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
641 if (rv != CKR_OK)
642 {
643 plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
644 pfreeany(slots);
645 return;
646 }
647
648 /* look in every slot for certificate objects */
649 for (i = 0; i < slot_count; i++)
650 {
651 CK_SLOT_ID slot = slots[i];
652 CK_SLOT_INFO info;
653 CK_SESSION_HANDLE session;
654
655 rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
656
657 if (rv != CKR_OK)
658 {
659 plog("error in C_GetSlotInfo: %s"
660 , enum_show(&pkcs11_return_names, rv));
661 continue;
662 }
663
664 if (!(info.flags & CKF_TOKEN_PRESENT))
665 {
666 plog("no token present in slot %lu", slot);
667 continue;
668 }
669
670 rv = pkcs11_functions->C_OpenSession(slot
671 , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
672 if (rv != CKR_OK)
673 {
674 plog("failed to open a session on slot %lu: %s"
675 , slot, enum_show(&pkcs11_return_names, rv));
676 continue;
677 }
678 DBG(DBG_CONTROLMORE,
679 DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
680 )
681 scx_find_cert_objects(slot, session);
682
683 rv = pkcs11_functions->C_CloseSession(session);
684 if (rv != CKR_OK)
685 {
686 plog("error in C_CloseSession: %s"
687 , enum_show(&pkcs11_return_names, rv));
688 }
689 }
690 pfreeany(slots);
691 }
692 #endif
693
694 /*
695 * load and initialize PKCS#11 cryptoki module
696 *
697 * init_args should be unused when we have a PKCS#11 compliant module,
698 * but NSS softoken breaks that API.
699 */
700 void
701 scx_init(const char* module, const char *init_args)
702 {
703 #ifdef SMARTCARD
704 CK_C_INITIALIZE_ARGS args = { .pReserved = init_args, };
705 CK_RV rv;
706
707 if (scx_initialized)
708 {
709 plog("weird - pkcs11 module seems already to be initialized");
710 return;
711 }
712
713 if (module == NULL)
714 #ifdef PKCS11_DEFAULT_LIB
715 module = PKCS11_DEFAULT_LIB;
716 #else
717 {
718 plog("no pkcs11 module defined");
719 return;
720 }
721 #endif
722
723 DBG(DBG_CONTROL | DBG_CRYPT,
724 DBG_log("pkcs11 module '%s' loading...", module)
725 )
726 pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
727 if (pkcs11_module == NULL)
728 {
729 plog("failed to load pkcs11 module '%s'", module);
730 return;
731 }
732
733 DBG(DBG_CONTROL | DBG_CRYPT,
734 DBG_log("pkcs11 module initializing...")
735 )
736 rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
737 if (rv != CKR_OK)
738 {
739 plog("failed to initialize pkcs11 module: %s"
740 , enum_show(&pkcs11_return_names, rv));
741 return;
742 }
743
744 scx_initialized = TRUE;
745 DBG(DBG_CONTROL | DBG_CRYPT,
746 DBG_log("pkcs11 module loaded and initialized")
747 )
748
749 scx_find_all_cert_objects();
750 #endif
751 }
752
753 /*
754 * finalize and unload PKCS#11 cryptoki module
755 */
756 void
757 scx_finalize(void)
758 {
759 #ifdef SMARTCARD
760 while (smartcards != NULL)
761 {
762 scx_release(smartcards);
763 }
764
765 if (pkcs11_functions != NULL_PTR)
766 {
767 pkcs11_functions->C_Finalize(NULL_PTR);
768 pkcs11_functions = NULL_PTR;
769 }
770
771 if (pkcs11_module != NULL)
772 {
773 scx_unload_pkcs11_module(pkcs11_module);
774 pkcs11_module = NULL;
775 }
776
777 scx_initialized = FALSE;
778 DBG(DBG_CONTROL | DBG_CRYPT,
779 DBG_log("pkcs11 module finalized and unloaded")
780 )
781 #endif
782 }
783
784 /*
785 * does a filename contain the token %smartcard?
786 */
787 bool
788 scx_on_smartcard(const char *filename)
789 {
790 return strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0;
791 }
792
793 #ifdef SMARTCARD
794 /*
795 * find a specific object on the smartcard
796 */
797 static bool
798 scx_pkcs11_find_object( CK_SESSION_HANDLE session,
799 CK_OBJECT_HANDLE_PTR object,
800 CK_OBJECT_CLASS class,
801 const char* id)
802 {
803 size_t len;
804 char buf[BUF_LEN];
805 CK_RV rv;
806 CK_ULONG obj_count = 0;
807 CK_ULONG attr_count = 1;
808
809 CK_ATTRIBUTE attr[] = {
810 { CKA_CLASS, &class, sizeof(class) },
811 { CKA_ID, &buf, 0L }
812 };
813
814 if (id != NULL)
815 {
816 ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
817 attr[1].ulValueLen = len;
818 attr_count = 2;
819 }
820
821 /* get info for certificate with id */
822 rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
823 if (rv != CKR_OK)
824 {
825 plog("error in C_FindObjectsInit: %s"
826 , enum_show(&pkcs11_return_names, rv));
827 return FALSE;
828 }
829
830 rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
831 if (rv != CKR_OK)
832 {
833 plog("error in C_FindObjects: %s"
834 , enum_show(&pkcs11_return_names, rv));
835 return FALSE;
836 }
837
838 rv = pkcs11_functions->C_FindObjectsFinal(session);
839 if (rv != CKR_OK)
840 {
841 plog("error in C_FindObjectsFinal: %s"
842 , enum_show(&pkcs11_return_names, rv));
843 return FALSE;
844 }
845
846 return (obj_count != 0);
847 }
848
849 /*
850 * check if a given certificate object id is found in a slot
851 */
852 static bool
853 scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
854 {
855 CK_SESSION_HANDLE session;
856 CK_OBJECT_HANDLE object;
857 CK_SLOT_INFO info;
858
859 CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
860
861 if (rv != CKR_OK)
862 {
863 plog("error in C_GetSlotInfo: %s"
864 , enum_show(&pkcs11_return_names, rv));
865 return FALSE;
866 }
867
868 if (!(info.flags & CKF_TOKEN_PRESENT))
869 {
870 plog("no token present in slot %lu", slot);
871 return FALSE;
872 }
873
874 rv = pkcs11_functions->C_OpenSession(slot
875 , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
876 if (rv != CKR_OK)
877 {
878 plog("failed to open a session on slot %lu: %s"
879 , slot, enum_show(&pkcs11_return_names, rv));
880 return FALSE;
881 }
882 DBG(DBG_CONTROLMORE,
883 DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
884 )
885
886 /* check if there is a certificate on the card in the specified slot */
887 if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
888 {
889 sc->slot = slot;
890 sc->any_slot = FALSE;
891 sc->session = session;
892 sc->session_opened = TRUE;
893 return TRUE;
894 }
895
896 rv = pkcs11_functions->C_CloseSession(session);
897 if (rv != CKR_OK)
898 {
899 plog("error in C_CloseSession: %s"
900 , enum_show(&pkcs11_return_names, rv));
901 }
902 return FALSE;
903 }
904 #endif
905
906 /*
907 * Connect to the smart card in the reader and select the correct slot
908 */
909 bool
910 scx_establish_context(smartcard_t *sc)
911 {
912 #ifdef SMARTCARD
913 bool id_found = FALSE;
914
915 if (!scx_initialized)
916 {
917 plog("pkcs11 module not initialized");
918 return FALSE;
919 }
920
921 if (sc->session_opened)
922 {
923 DBG(DBG_CONTROL | DBG_CRYPT,
924 DBG_log("pkcs11 session #%ld already open", sc->session)
925 )
926 return TRUE;
927 }
928
929 if (!sc->any_slot)
930 id_found = scx_find_cert_id_in_slot(sc, sc->slot);
931
932 if (!id_found)
933 {
934 CK_RV rv;
935 CK_SLOT_ID slot;
936 CK_SLOT_ID_PTR slots = NULL_PTR;
937 CK_ULONG slot_count = 0;
938 CK_ULONG i;
939
940 /* read size, always returns CKR_OK ! */
941 rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
942
943 /* allocate memory for the slots */
944 slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
945
946 rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
947 if (rv != CKR_OK)
948 {
949 plog("error in C_GetSlotList: %s"
950 , enum_show(&pkcs11_return_names, rv));
951 pfreeany(slots);
952 return FALSE;
953 }
954
955 /* look in every slot for a certificate with a given object ID */
956 for (i = 0; i < slot_count; i++)
957 {
958 slot = slots[i];
959 id_found = scx_find_cert_id_in_slot(sc, slot);
960 if (id_found)
961 break;
962 }
963 pfreeany(slots)
964 }
965
966 if (id_found)
967 {
968 DBG(DBG_CONTROL | DBG_CRYPT,
969 DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
970 DBG_log("pkcs11 session #%ld opened", sc->session)
971 )
972 }
973 else
974 {
975 plog(" no certificate with id %s found on smartcard", sc->id);
976 }
977 return id_found;
978 #else
979 plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
980 return FALSE;
981 #endif
982 }
983
984 /*
985 * log in to a session
986 */
987 bool
988 scx_login(smartcard_t *sc)
989 {
990 #ifdef SMARTCARD
991 CK_RV rv;
992
993 if (sc->logged_in)
994 {
995 DBG(DBG_CONTROL | DBG_CRYPT,
996 DBG_log("pkcs11 session #%ld login already done", sc->session)
997 )
998 return TRUE;
999 }
1000
1001 if (sc->pin.ptr == NULL)
1002 {
1003 plog("unable to log in without PIN!");
1004 return FALSE;
1005 }
1006
1007 if (!sc->session_opened)
1008 {
1009 plog("session not opened");
1010 return FALSE;
1011 }
1012
1013 rv = pkcs11_functions->C_Login(sc->session, CKU_USER
1014 , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1015 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
1016 {
1017 plog("unable to login: %s"
1018 , enum_show(&pkcs11_return_names, rv));
1019 return FALSE;
1020 }
1021 DBG(DBG_CONTROL | DBG_CRYPT,
1022 DBG_log("pkcs11 session #%ld login successful", sc->session)
1023 )
1024 sc->logged_in = TRUE;
1025 return TRUE;
1026 #else
1027 return FALSE;
1028 #endif
1029 }
1030
1031 #ifdef SMARTCARD
1032 /*
1033 * logout from a session
1034 */
1035 static void
1036 scx_logout(smartcard_t *sc)
1037 {
1038 CK_RV rv;
1039
1040 rv = pkcs11_functions->C_Logout(sc->session);
1041 if (rv != CKR_OK)
1042 plog("error in C_Logout: %s"
1043 , enum_show(&pkcs11_return_names, rv));
1044 else
1045 DBG(DBG_CONTROL | DBG_CRYPT,
1046 DBG_log("pkcs11 session #%ld logout", sc->session)
1047 )
1048 sc->logged_in = FALSE;
1049 }
1050 #endif
1051
1052
1053 /*
1054 * Release context and disconnect from card
1055 */
1056 void
1057 scx_release_context(smartcard_t *sc)
1058 {
1059 #ifdef SMARTCARD
1060 CK_RV rv;
1061
1062 if (!scx_initialized)
1063 return;
1064
1065 if (sc->session_opened)
1066 {
1067 if (sc->logged_in)
1068 scx_logout(sc);
1069
1070 sc->session_opened = FALSE;
1071
1072 rv = pkcs11_functions->C_CloseSession(sc->session);
1073 if (rv != CKR_OK)
1074 plog("error in C_CloseSession: %s"
1075 , enum_show(&pkcs11_return_names, rv));
1076 else
1077 DBG(DBG_CONTROL | DBG_CRYPT,
1078 DBG_log("pkcs11 session #%ld closed", sc->session)
1079 )
1080 }
1081 #endif
1082 }
1083
1084 /*
1085 * Load host certificate from smartcard
1086 */
1087 bool
1088 scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
1089 , bool *cached)
1090 {
1091 #ifdef SMARTCARD /* compile with smartcard support */
1092 CK_OBJECT_HANDLE object;
1093
1094 const char *number_slot_id = filename + strlen(SCX_TOKEN);
1095
1096 smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
1097
1098 /* return the smartcard object */
1099 *scp = sc;
1100
1101 /* is there a cached smartcard certificate? */
1102 *cached = sc->last_cert.type != CERT_NONE
1103 && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
1104
1105 if (*cached)
1106 {
1107 *cert = sc->last_cert;
1108 plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
1109 , sc->number
1110 , scx_print_slot(sc, "")
1111 , sc->id
1112 , sc->label);
1113 return TRUE;
1114 }
1115
1116 if (!scx_establish_context(sc))
1117 {
1118 scx_release_context(sc);
1119 return FALSE;
1120 }
1121
1122 /* find the certificate object */
1123 if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
1124 {
1125 scx_release_context(sc);
1126 return FALSE;
1127 }
1128
1129 /* retrieve the certificate object */
1130 if (!scx_find_cert_object(sc->session, object, sc, cert))
1131 {
1132 scx_release_context(sc);
1133 return FALSE;
1134 }
1135
1136 if (!pkcs11_keep_state)
1137 scx_release_context(sc);
1138
1139 plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
1140 , sc->number
1141 , scx_print_slot(sc, "")
1142 , sc->id
1143 , sc->label);
1144
1145 return TRUE;
1146 #else
1147 plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
1148 return FALSE;
1149 #endif
1150 }
1151
1152 /*
1153 * parse slot number and key id
1154 * the following syntax is allowed
1155 * number slot id
1156 * %smartcard 1 - -
1157 * %smartcard#2 2 - -
1158 * %smartcard0 - 0 -
1159 * %smartcard:45 - - 45
1160 * %smartcard0:45 - 0 45
1161 */
1162 smartcard_t*
1163 scx_parse_number_slot_id(const char *number_slot_id)
1164 {
1165 int len = strlen(number_slot_id);
1166 smartcard_t *sc = alloc_thing(smartcard_t, "smartcard");
1167
1168 /* assign default values */
1169 *sc = empty_sc;
1170
1171 if (len == 0) /* default: use certificate #1 */
1172 {
1173 sc->number = 1;
1174 }
1175 else if (*number_slot_id == '#') /* #number scheme */
1176 {
1177 err_t ugh;
1178 unsigned long ul;
1179
1180 ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
1181 if (ugh == NULL)
1182 sc->number = (int)ul;
1183 else
1184 plog("error parsing smartcard number: %s", ugh);
1185 }
1186 else /* slot:id scheme */
1187 {
1188 int slot_len = len;
1189 char *p = strchr(number_slot_id, ':');
1190
1191 if (p != NULL)
1192 {
1193 int id_len = len - (p + 1 - number_slot_id);
1194 slot_len -= (1 + id_len);
1195
1196 if (id_len > 0) /* we have an id */
1197 sc->id = p + 1;
1198 }
1199 if (slot_len > 0) /* we have a slot */
1200 {
1201 err_t ugh = NULL;
1202 unsigned long ul;
1203
1204 ugh = atoul(number_slot_id, slot_len, 10, &ul);
1205 if (ugh == NULL)
1206 {
1207 sc->slot = ul;
1208 sc->any_slot = FALSE;
1209 }
1210 else
1211 plog("error parsing smartcard slot number: %s", ugh);
1212 }
1213 }
1214 /* unshare the id string */
1215 sc->id = clone_str(sc->id, "key id");
1216 return sc;
1217 }
1218
1219 /*
1220 * Verify pin on card
1221 */
1222 bool
1223 scx_verify_pin(smartcard_t *sc)
1224 {
1225 #ifdef SMARTCARD
1226 CK_RV rv;
1227
1228 if (!sc->pinpad)
1229 sc->valid = FALSE;
1230
1231 if (sc->pin.ptr == NULL)
1232 {
1233 plog("unable to verify without PIN");
1234 return FALSE;
1235 }
1236
1237 /* establish context */
1238 if (!scx_establish_context(sc))
1239 {
1240 scx_release_context(sc);
1241 return FALSE;
1242 }
1243
1244 rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
1245 (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1246 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
1247 {
1248 sc->valid = TRUE;
1249 sc->logged_in = TRUE;
1250 DBG(DBG_CONTROL | DBG_CRYPT,
1251 DBG_log((rv == CKR_OK)
1252 ? "PIN code correct"
1253 : "already logged in, no PIN entry required");
1254 DBG_log("pkcs11 session #%ld login successful", sc->session)
1255 )
1256 }
1257 else
1258 {
1259 DBG(DBG_CONTROL | DBG_CRYPT,
1260 DBG_log("PIN code incorrect")
1261 )
1262 }
1263 if (!pkcs11_keep_state)
1264 scx_release_context(sc);
1265 #else
1266 sc->valid = FALSE;
1267 #endif
1268 return sc->valid;
1269 }
1270
1271 /*
1272 * Sign hash on smartcard
1273 */
1274 bool
1275 scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
1276 , u_char *out, size_t outlen)
1277 {
1278 #ifdef SMARTCARD
1279 CK_RV rv;
1280 CK_OBJECT_HANDLE object;
1281 CK_ULONG siglen = (CK_ULONG)outlen;
1282 CK_BBOOL sign_flag, decrypt_flag;
1283 CK_ATTRIBUTE attr[] = {
1284 { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
1285 { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
1286 };
1287
1288 if (!sc->logged_in)
1289 return FALSE;
1290
1291 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1292 {
1293 plog("unable to find private key with id '%s'", sc->id);
1294 return FALSE;
1295 }
1296
1297 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1298 if (rv != CKR_OK)
1299 {
1300 plog("couldn't read the private key attributes: %s"
1301 , enum_show(&pkcs11_return_names, rv));
1302 return FALSE;
1303 }
1304 DBG(DBG_CONTROL,
1305 DBG_log("RSA key flags: sign = %s, decrypt = %s"
1306 , (sign_flag)? "true":"false"
1307 , (decrypt_flag)? "true":"false")
1308 )
1309
1310 if (sign_flag)
1311 {
1312 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1313
1314 rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
1315 if (rv != CKR_OK)
1316 {
1317 plog("error in C_SignInit: %s"
1318 , enum_show(&pkcs11_return_names, rv));
1319 return FALSE;
1320 }
1321
1322 rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
1323 , out, &siglen);
1324 if (rv != CKR_OK)
1325 {
1326 plog("error in C_Sign: %s"
1327 , enum_show(&pkcs11_return_names, rv));
1328 return FALSE;
1329 }
1330 }
1331 else if (decrypt_flag)
1332 {
1333 CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
1334 size_t padlen;
1335 u_char *p = out ;
1336
1337 /* PKCS#1 v1.5 8.1 encryption-block formatting */
1338 *p++ = 0x00;
1339 *p++ = 0x01; /* BT (block type) 01 */
1340 padlen = outlen - 3 - inlen;
1341 memset(p, 0xFF, padlen);
1342 p += padlen;
1343 *p++ = 0x00;
1344 memcpy(p, in, inlen);
1345
1346 rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
1347 if (rv != CKR_OK)
1348 {
1349 plog("error in C_DecryptInit: %s"
1350 , enum_show(&pkcs11_return_names, rv));
1351 return FALSE;
1352 }
1353
1354 rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
1355 , out, &siglen);
1356 if (rv != CKR_OK)
1357 {
1358 plog("error in C_Decrypt: %s"
1359 , enum_show(&pkcs11_return_names, rv));
1360 return FALSE;
1361 }
1362 }
1363 else
1364 {
1365 plog("private key has neither sign nor decrypt flag set");
1366 return FALSE;
1367 }
1368
1369 if (siglen > (CK_ULONG)outlen)
1370 {
1371 plog("signature length (%lu) larger than allocated buffer (%d)"
1372 , siglen, (int)outlen);
1373 return FALSE;
1374 }
1375 return TRUE;
1376 #else
1377 return FALSE;
1378 #endif
1379 }
1380
1381 /*
1382 * encrypt data block with an RSA public key
1383 */
1384 bool
1385 scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
1386 , u_char *out, size_t *outlen)
1387 {
1388 #ifdef SMARTCARD
1389 CK_RV rv;
1390 CK_OBJECT_HANDLE object;
1391 CK_ULONG len = (CK_ULONG)(*outlen);
1392 CK_BBOOL encrypt_flag;
1393 CK_ATTRIBUTE attr[] = {
1394 { CKA_MODULUS, NULL_PTR, 0L },
1395 { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
1396 { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
1397 };
1398 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1399
1400 if (!scx_establish_context(sc))
1401 {
1402 scx_release_context(sc);
1403 return FALSE;
1404 }
1405
1406 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
1407 {
1408 plog("unable to find public key with id '%s'", sc->id);
1409 return FALSE;
1410 }
1411
1412 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
1413 if (rv != CKR_OK)
1414 {
1415 plog("couldn't read the public key attributes: %s"
1416 , enum_show(&pkcs11_return_names, rv));
1417 scx_release_context(sc);
1418 return FALSE;
1419 }
1420
1421 if (!encrypt_flag)
1422 {
1423 plog("public key cannot be used for encryption");
1424 scx_release_context(sc);
1425 return FALSE;
1426 }
1427
1428 /* there must be enough space left for the PKCS#1 v1.5 padding */
1429 if (inlen > attr[0].ulValueLen - 11)
1430 {
1431 plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
1432 , (int)inlen, attr[0].ulValueLen - 11);
1433 if (!pkcs11_keep_state)
1434 scx_release_context(sc);
1435 return FALSE;
1436 }
1437
1438 rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
1439
1440 if (rv != CKR_OK)
1441 {
1442 if (rv == CKR_FUNCTION_NOT_SUPPORTED)
1443 {
1444 RSA_public_key_t rsa;
1445 chunk_t plain_text = {in, inlen};
1446 chunk_t cipher_text;
1447
1448 DBG(DBG_CONTROL,
1449 DBG_log("doing RSA encryption in software")
1450 )
1451 attr[0].pValue = alloc_bytes(attr[0].ulValueLen, "modulus");
1452 attr[1].pValue = alloc_bytes(attr[1].ulValueLen, "exponent");
1453
1454 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1455 if (rv != CKR_OK)
1456 {
1457 plog("couldn't read modulus and public exponent: %s"
1458 , enum_show(&pkcs11_return_names, rv));
1459 pfree(attr[0].pValue);
1460 pfree(attr[1].pValue);
1461 scx_release_context(sc);
1462 return FALSE;
1463 }
1464 rsa.k = attr[0].ulValueLen;
1465 n_to_mpz(&rsa.n, attr[0].pValue, attr[0].ulValueLen);
1466 n_to_mpz(&rsa.e, attr[1].pValue, attr[1].ulValueLen);
1467 pfree(attr[0].pValue);
1468 pfree(attr[1].pValue);
1469
1470 cipher_text = RSA_encrypt(&rsa, plain_text);
1471 free_RSA_public_content(&rsa);
1472 if (cipher_text.ptr == NULL)
1473 {
1474 plog("smartcard input data length is too large");
1475 if (!pkcs11_keep_state)
1476 scx_release_context(sc);
1477 return FALSE;
1478 }
1479
1480 memcpy(out, cipher_text.ptr, cipher_text.len);
1481 *outlen = cipher_text.len;
1482 freeanychunk(cipher_text);
1483 if (!pkcs11_keep_state)
1484 scx_release_context(sc);
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, 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, 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 = (strncmp(keyid, SCX_TOKEN, strlen(SCX_TOKEN)) == 0)
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 clonetochunk(sc->pin, pin, strlen(pin), "pin");
1763 break;
1764 }
1765
1766 /* wrong pin - we try another round */
1767 sc->pin = empty_chunk;
1768 }
1769
1770 if (sc->valid)
1771 whack_log(RC_SUCCESS, "valid PIN");
1772 else
1773 whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
1774 #else
1775 sc->valid = FALSE;
1776 whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
1777 #endif
1778 return sc->valid;
1779 }
1780
1781
1782 /*
1783 * free the pin code
1784 */
1785 void
1786 scx_free_pin(chunk_t *pin)
1787 {
1788 if (pin->ptr != NULL)
1789 {
1790 /* clear pin field in memory */
1791 memset(pin->ptr, '\0', pin->len);
1792 pfree(pin->ptr);
1793 *pin = empty_chunk;
1794 }
1795 }
1796
1797 /*
1798 * frees a smartcard record
1799 */
1800 void
1801 scx_free(smartcard_t *sc)
1802 {
1803 if (sc != NULL)
1804 {
1805 scx_release_context(sc);
1806 pfreeany(sc->id);
1807 pfreeany(sc->label);
1808 scx_free_pin(&sc->pin);
1809 pfree(sc);
1810 }
1811 }
1812
1813 /* release of a smartcard record decreases the count by one
1814 " the record is freed when the counter reaches zero
1815 */
1816 void
1817 scx_release(smartcard_t *sc)
1818 {
1819 if (sc != NULL && --sc->count == 0)
1820 {
1821 smartcard_t **pp = &smartcards;
1822 while (*pp != sc)
1823 pp = &(*pp)->next;
1824 *pp = sc->next;
1825 release_cert(sc->last_cert);
1826 scx_free(sc);
1827 }
1828 }
1829
1830 /*
1831 * compare two smartcard records by comparing their slots and ids
1832 */
1833 static bool
1834 scx_same(smartcard_t *a, smartcard_t *b)
1835 {
1836 if (a->number && b->number)
1837 {
1838 /* same number */
1839 return a->number == b->number;
1840 }
1841 else
1842 {
1843 /* same id and/or same slot */
1844 return (!a->id || (b->id && streq(a->id, b->id)))
1845 && (a->any_slot || b->any_slot || a->slot == b->slot);
1846 }
1847 }
1848
1849 /* for each link pointing to the smartcard record
1850 " increase the count by one
1851 */
1852 void
1853 scx_share(smartcard_t *sc)
1854 {
1855 if (sc != NULL)
1856 sc->count++;
1857 }
1858
1859 /*
1860 * adds a smartcard record to the chained list
1861 */
1862 smartcard_t*
1863 scx_add(smartcard_t *smartcard)
1864 {
1865 smartcard_t *sc = smartcards;
1866 smartcard_t **psc = &smartcards;
1867
1868 while (sc != NULL)
1869 {
1870 if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
1871 {
1872 scx_free(smartcard);
1873 return sc;
1874 }
1875 psc = &sc->next;
1876 sc = sc->next;
1877 }
1878
1879 /* insert new smartcard record at the end of the chain */
1880 *psc = smartcard;
1881 smartcard->number = ++sc_number;
1882 smartcard->count = 1;
1883 DBG(DBG_CONTROL | DBG_PARSING,
1884 DBG_log(" smartcard #%d added", sc_number)
1885 )
1886 return smartcard;
1887 }
1888
1889 /*
1890 * get the smartcard that belongs to an X.509 certificate
1891 */
1892 smartcard_t*
1893 scx_get(x509cert_t *cert)
1894 {
1895 smartcard_t *sc = smartcards;
1896
1897 while (sc != NULL)
1898 {
1899 if (sc->last_cert.u.x509 == cert)
1900 return sc;
1901 sc = sc->next;
1902 }
1903 return NULL;
1904 }
1905
1906 /*
1907 * prints either the slot number or 'any slot'
1908 */
1909 char *
1910 scx_print_slot(smartcard_t *sc, const char *whitespace)
1911 {
1912 char *buf = temporary_cyclic_buffer();
1913
1914 if (sc->any_slot)
1915 snprintf(buf, BUF_LEN, "any slot");
1916 else
1917 snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
1918 return buf;
1919 }
1920
1921 /*
1922 * list all smartcard info records in a chained list
1923 */
1924 void
1925 scx_list(bool utc)
1926 {
1927 smartcard_t *sc = smartcards;
1928
1929 if (sc != NULL)
1930 {
1931 whack_log(RC_COMMENT, " ");
1932 whack_log(RC_COMMENT, "List of Smartcard Objects:");
1933 whack_log(RC_COMMENT, " ");
1934 }
1935
1936 while (sc != NULL)
1937 {
1938 whack_log(RC_COMMENT, "%s, #%d, count: %d"
1939 , timetoa(&sc->last_load, utc)
1940 , sc->number
1941 , sc->count);
1942 whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
1943 , scx_print_slot(sc, " ")
1944 , sc->session_opened? "opened" : "closed"
1945 , sc->logged_in? "in" : "out"
1946 , sc->pinpad? "pin pad"
1947 : ((sc->pin.ptr == NULL)? "no pin"
1948 : sc->valid? "valid pin" : "invalid pin"));
1949 if (sc->id != NULL)
1950 whack_log(RC_COMMENT, " id: %s", sc->id);
1951 if (sc->label != NULL)
1952 whack_log(RC_COMMENT, " label: '%s'", sc->label);
1953 if (sc->last_cert.type == CERT_X509_SIGNATURE)
1954 {
1955 char buf[BUF_LEN];
1956
1957 dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
1958 whack_log(RC_COMMENT, " subject: '%s'", buf);
1959 }
1960 sc = sc->next;
1961 }
1962 }