067d0f046d974f8eefe23a6377d450ceb34d4471
[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 * init_args should be unused when we have a PKCS#11 compliant module,
696 * but NSS softoken breaks that API.
697 */
698 void
699 scx_init(const char* module, const char *init_args)
700 {
701 #ifdef SMARTCARD
702 CK_C_INITIALIZE_ARGS args = { .pReserved = init_args, };
703 CK_RV rv;
704
705 if (scx_initialized)
706 {
707 plog("weird - pkcs11 module seems already to be initialized");
708 return;
709 }
710
711 if (module == NULL)
712 #ifdef PKCS11_DEFAULT_LIB
713 module = PKCS11_DEFAULT_LIB;
714 #else
715 {
716 plog("no pkcs11 module defined");
717 return;
718 }
719 #endif
720
721 DBG(DBG_CONTROL | DBG_CRYPT,
722 DBG_log("pkcs11 module '%s' loading...", module)
723 )
724 pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
725 if (pkcs11_module == NULL)
726 {
727 plog("failed to load pkcs11 module '%s'", module);
728 return;
729 }
730
731 DBG(DBG_CONTROL | DBG_CRYPT,
732 DBG_log("pkcs11 module initializing...")
733 )
734 rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
735 if (rv != CKR_OK)
736 {
737 plog("failed to initialize pkcs11 module: %s"
738 , enum_show(&pkcs11_return_names, rv));
739 return;
740 }
741
742 scx_initialized = TRUE;
743 DBG(DBG_CONTROL | DBG_CRYPT,
744 DBG_log("pkcs11 module loaded and initialized")
745 )
746
747 scx_find_all_cert_objects();
748 #endif
749 }
750
751 /*
752 * finalize and unload PKCS#11 cryptoki module
753 */
754 void
755 scx_finalize(void)
756 {
757 #ifdef SMARTCARD
758 while (smartcards != NULL)
759 {
760 scx_release(smartcards);
761 }
762
763 if (pkcs11_functions != NULL_PTR)
764 {
765 pkcs11_functions->C_Finalize(NULL_PTR);
766 pkcs11_functions = NULL_PTR;
767 }
768
769 if (pkcs11_module != NULL)
770 {
771 scx_unload_pkcs11_module(pkcs11_module);
772 pkcs11_module = NULL;
773 }
774
775 scx_initialized = FALSE;
776 DBG(DBG_CONTROL | DBG_CRYPT,
777 DBG_log("pkcs11 module finalized and unloaded")
778 )
779 #endif
780 }
781
782 /*
783 * does a filename contain the token %smartcard?
784 */
785 bool
786 scx_on_smartcard(const char *filename)
787 {
788 return strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0;
789 }
790
791 #ifdef SMARTCARD
792 /*
793 * find a specific object on the smartcard
794 */
795 static bool
796 scx_pkcs11_find_object( CK_SESSION_HANDLE session,
797 CK_OBJECT_HANDLE_PTR object,
798 CK_OBJECT_CLASS class,
799 const char* id)
800 {
801 size_t len;
802 char buf[BUF_LEN];
803 CK_RV rv;
804 CK_ULONG obj_count = 0;
805 CK_ULONG attr_count = 1;
806
807 CK_ATTRIBUTE attr[] = {
808 { CKA_CLASS, &class, sizeof(class) },
809 { CKA_ID, &buf, 0L }
810 };
811
812 if (id != NULL)
813 {
814 ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
815 attr[1].ulValueLen = len;
816 attr_count = 2;
817 }
818
819 /* get info for certificate with id */
820 rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
821 if (rv != CKR_OK)
822 {
823 plog("error in C_FindObjectsInit: %s"
824 , enum_show(&pkcs11_return_names, rv));
825 return FALSE;
826 }
827
828 rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
829 if (rv != CKR_OK)
830 {
831 plog("error in C_FindObjects: %s"
832 , enum_show(&pkcs11_return_names, rv));
833 return FALSE;
834 }
835
836 rv = pkcs11_functions->C_FindObjectsFinal(session);
837 if (rv != CKR_OK)
838 {
839 plog("error in C_FindObjectsFinal: %s"
840 , enum_show(&pkcs11_return_names, rv));
841 return FALSE;
842 }
843
844 return (obj_count != 0);
845 }
846
847 /*
848 * check if a given certificate object id is found in a slot
849 */
850 static bool
851 scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
852 {
853 CK_SESSION_HANDLE session;
854 CK_OBJECT_HANDLE object;
855 CK_SLOT_INFO info;
856
857 CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
858
859 if (rv != CKR_OK)
860 {
861 plog("error in C_GetSlotInfo: %s"
862 , enum_show(&pkcs11_return_names, rv));
863 return FALSE;
864 }
865
866 if (!(info.flags & CKF_TOKEN_PRESENT))
867 {
868 plog("no token present in slot %lu", slot);
869 return FALSE;
870 }
871
872 rv = pkcs11_functions->C_OpenSession(slot
873 , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
874 if (rv != CKR_OK)
875 {
876 plog("failed to open a session on slot %lu: %s"
877 , slot, enum_show(&pkcs11_return_names, rv));
878 return FALSE;
879 }
880 DBG(DBG_CONTROLMORE,
881 DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
882 )
883
884 /* check if there is a certificate on the card in the specified slot */
885 if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
886 {
887 sc->slot = slot;
888 sc->any_slot = FALSE;
889 sc->session = session;
890 sc->session_opened = TRUE;
891 return TRUE;
892 }
893
894 rv = pkcs11_functions->C_CloseSession(session);
895 if (rv != CKR_OK)
896 {
897 plog("error in C_CloseSession: %s"
898 , enum_show(&pkcs11_return_names, rv));
899 }
900 return FALSE;
901 }
902 #endif
903
904 /*
905 * Connect to the smart card in the reader and select the correct slot
906 */
907 bool
908 scx_establish_context(smartcard_t *sc)
909 {
910 #ifdef SMARTCARD
911 bool id_found = FALSE;
912
913 if (!scx_initialized)
914 {
915 plog("pkcs11 module not initialized");
916 return FALSE;
917 }
918
919 if (sc->session_opened)
920 {
921 DBG(DBG_CONTROL | DBG_CRYPT,
922 DBG_log("pkcs11 session #%ld already open", sc->session)
923 )
924 return TRUE;
925 }
926
927 if (!sc->any_slot)
928 id_found = scx_find_cert_id_in_slot(sc, sc->slot);
929
930 if (!id_found)
931 {
932 CK_RV rv;
933 CK_SLOT_ID slot;
934 CK_SLOT_ID_PTR slots = NULL_PTR;
935 CK_ULONG slot_count = 0;
936 CK_ULONG i;
937
938 /* read size, always returns CKR_OK ! */
939 rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
940
941 /* allocate memory for the slots */
942 slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
943
944 rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
945 if (rv != CKR_OK)
946 {
947 plog("error in C_GetSlotList: %s"
948 , enum_show(&pkcs11_return_names, rv));
949 pfreeany(slots);
950 return FALSE;
951 }
952
953 /* look in every slot for a certificate with a given object ID */
954 for (i = 0; i < slot_count; i++)
955 {
956 slot = slots[i];
957 id_found = scx_find_cert_id_in_slot(sc, slot);
958 if (id_found)
959 break;
960 }
961 pfreeany(slots)
962 }
963
964 if (id_found)
965 {
966 DBG(DBG_CONTROL | DBG_CRYPT,
967 DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
968 DBG_log("pkcs11 session #%ld opened", sc->session)
969 )
970 }
971 else
972 {
973 plog(" no certificate with id %s found on smartcard", sc->id);
974 }
975 return id_found;
976 #else
977 plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
978 return FALSE;
979 #endif
980 }
981
982 /*
983 * log in to a session
984 */
985 bool
986 scx_login(smartcard_t *sc)
987 {
988 #ifdef SMARTCARD
989 CK_RV rv;
990
991 if (sc->logged_in)
992 {
993 DBG(DBG_CONTROL | DBG_CRYPT,
994 DBG_log("pkcs11 session #%ld login already done", sc->session)
995 )
996 return TRUE;
997 }
998
999 if (sc->pin.ptr == NULL)
1000 {
1001 plog("unable to log in without PIN!");
1002 return FALSE;
1003 }
1004
1005 if (!sc->session_opened)
1006 {
1007 plog("session not opened");
1008 return FALSE;
1009 }
1010
1011 rv = pkcs11_functions->C_Login(sc->session, CKU_USER
1012 , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1013 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
1014 {
1015 plog("unable to login: %s"
1016 , enum_show(&pkcs11_return_names, rv));
1017 return FALSE;
1018 }
1019 DBG(DBG_CONTROL | DBG_CRYPT,
1020 DBG_log("pkcs11 session #%ld login successful", sc->session)
1021 )
1022 sc->logged_in = TRUE;
1023 return TRUE;
1024 #else
1025 return FALSE;
1026 #endif
1027 }
1028
1029 #ifdef SMARTCARD
1030 /*
1031 * logout from a session
1032 */
1033 static void
1034 scx_logout(smartcard_t *sc)
1035 {
1036 CK_RV rv;
1037
1038 rv = pkcs11_functions->C_Logout(sc->session);
1039 if (rv != CKR_OK)
1040 plog("error in C_Logout: %s"
1041 , enum_show(&pkcs11_return_names, rv));
1042 else
1043 DBG(DBG_CONTROL | DBG_CRYPT,
1044 DBG_log("pkcs11 session #%ld logout", sc->session)
1045 )
1046 sc->logged_in = FALSE;
1047 }
1048 #endif
1049
1050
1051 /*
1052 * Release context and disconnect from card
1053 */
1054 void
1055 scx_release_context(smartcard_t *sc)
1056 {
1057 #ifdef SMARTCARD
1058 CK_RV rv;
1059
1060 if (!scx_initialized)
1061 return;
1062
1063 if (sc->session_opened)
1064 {
1065 if (sc->logged_in)
1066 scx_logout(sc);
1067
1068 sc->session_opened = FALSE;
1069
1070 rv = pkcs11_functions->C_CloseSession(sc->session);
1071 if (rv != CKR_OK)
1072 plog("error in C_CloseSession: %s"
1073 , enum_show(&pkcs11_return_names, rv));
1074 else
1075 DBG(DBG_CONTROL | DBG_CRYPT,
1076 DBG_log("pkcs11 session #%ld closed", sc->session)
1077 )
1078 }
1079 #endif
1080 }
1081
1082 /*
1083 * Load host certificate from smartcard
1084 */
1085 bool
1086 scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
1087 , bool *cached)
1088 {
1089 #ifdef SMARTCARD /* compile with smartcard support */
1090 CK_OBJECT_HANDLE object;
1091
1092 const char *number_slot_id = filename + strlen(SCX_TOKEN);
1093
1094 smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
1095
1096 /* return the smartcard object */
1097 *scp = sc;
1098
1099 /* is there a cached smartcard certificate? */
1100 *cached = sc->last_cert.type != CERT_NONE
1101 && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
1102
1103 if (*cached)
1104 {
1105 *cert = sc->last_cert;
1106 plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
1107 , sc->number
1108 , scx_print_slot(sc, "")
1109 , sc->id
1110 , sc->label);
1111 return TRUE;
1112 }
1113
1114 if (!scx_establish_context(sc))
1115 {
1116 scx_release_context(sc);
1117 return FALSE;
1118 }
1119
1120 /* find the certificate object */
1121 if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
1122 {
1123 scx_release_context(sc);
1124 return FALSE;
1125 }
1126
1127 /* retrieve the certificate object */
1128 if (!scx_find_cert_object(sc->session, object, sc, cert))
1129 {
1130 scx_release_context(sc);
1131 return FALSE;
1132 }
1133
1134 if (!pkcs11_keep_state)
1135 scx_release_context(sc);
1136
1137 plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
1138 , sc->number
1139 , scx_print_slot(sc, "")
1140 , sc->id
1141 , sc->label);
1142
1143 return TRUE;
1144 #else
1145 plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
1146 return FALSE;
1147 #endif
1148 }
1149
1150 /*
1151 * parse slot number and key id
1152 * the following syntax is allowed
1153 * number slot id
1154 * %smartcard 1 - -
1155 * %smartcard#2 2 - -
1156 * %smartcard0 - 0 -
1157 * %smartcard:45 - - 45
1158 * %smartcard0:45 - 0 45
1159 */
1160 smartcard_t*
1161 scx_parse_number_slot_id(const char *number_slot_id)
1162 {
1163 int len = strlen(number_slot_id);
1164 smartcard_t *sc = alloc_thing(smartcard_t, "smartcard");
1165
1166 /* assign default values */
1167 *sc = empty_sc;
1168
1169 if (len == 0) /* default: use certificate #1 */
1170 {
1171 sc->number = 1;
1172 }
1173 else if (*number_slot_id == '#') /* #number scheme */
1174 {
1175 err_t ugh;
1176 unsigned long ul;
1177
1178 ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
1179 if (ugh == NULL)
1180 sc->number = (int)ul;
1181 else
1182 plog("error parsing smartcard number: %s", ugh);
1183 }
1184 else /* slot:id scheme */
1185 {
1186 int slot_len = len;
1187 char *p = strchr(number_slot_id, ':');
1188
1189 if (p != NULL)
1190 {
1191 int id_len = len - (p + 1 - number_slot_id);
1192 slot_len -= (1 + id_len);
1193
1194 if (id_len > 0) /* we have an id */
1195 sc->id = p + 1;
1196 }
1197 if (slot_len > 0) /* we have a slot */
1198 {
1199 err_t ugh = NULL;
1200 unsigned long ul;
1201
1202 ugh = atoul(number_slot_id, slot_len, 10, &ul);
1203 if (ugh == NULL)
1204 {
1205 sc->slot = ul;
1206 sc->any_slot = FALSE;
1207 }
1208 else
1209 plog("error parsing smartcard slot number: %s", ugh);
1210 }
1211 }
1212 /* unshare the id string */
1213 sc->id = clone_str(sc->id, "key id");
1214 return sc;
1215 }
1216
1217 /*
1218 * Verify pin on card
1219 */
1220 bool
1221 scx_verify_pin(smartcard_t *sc)
1222 {
1223 #ifdef SMARTCARD
1224 CK_RV rv;
1225
1226 if (!sc->pinpad)
1227 sc->valid = FALSE;
1228
1229 if (sc->pin.ptr == NULL)
1230 {
1231 plog("unable to verify without PIN");
1232 return FALSE;
1233 }
1234
1235 /* establish context */
1236 if (!scx_establish_context(sc))
1237 {
1238 scx_release_context(sc);
1239 return FALSE;
1240 }
1241
1242 rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
1243 (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
1244 if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
1245 {
1246 sc->valid = TRUE;
1247 sc->logged_in = TRUE;
1248 DBG(DBG_CONTROL | DBG_CRYPT,
1249 DBG_log((rv == CKR_OK)
1250 ? "PIN code correct"
1251 : "already logged in, no PIN entry required");
1252 DBG_log("pkcs11 session #%ld login successful", sc->session)
1253 )
1254 }
1255 else
1256 {
1257 DBG(DBG_CONTROL | DBG_CRYPT,
1258 DBG_log("PIN code incorrect")
1259 )
1260 }
1261 if (!pkcs11_keep_state)
1262 scx_release_context(sc);
1263 #else
1264 sc->valid = FALSE;
1265 #endif
1266 return sc->valid;
1267 }
1268
1269 /*
1270 * Sign hash on smartcard
1271 */
1272 bool
1273 scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
1274 , u_char *out, size_t outlen)
1275 {
1276 #ifdef SMARTCARD
1277 CK_RV rv;
1278 CK_OBJECT_HANDLE object;
1279 CK_ULONG siglen = (CK_ULONG)outlen;
1280 CK_BBOOL sign_flag, decrypt_flag;
1281 CK_ATTRIBUTE attr[] = {
1282 { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
1283 { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
1284 };
1285
1286 if (!sc->logged_in)
1287 return FALSE;
1288
1289 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1290 {
1291 plog("unable to find private key with id '%s'", sc->id);
1292 return FALSE;
1293 }
1294
1295 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1296 if (rv != CKR_OK)
1297 {
1298 plog("couldn't read the private key attributes: %s"
1299 , enum_show(&pkcs11_return_names, rv));
1300 return FALSE;
1301 }
1302 DBG(DBG_CONTROL,
1303 DBG_log("RSA key flags: sign = %s, decrypt = %s"
1304 , (sign_flag)? "true":"false"
1305 , (decrypt_flag)? "true":"false")
1306 )
1307
1308 if (sign_flag)
1309 {
1310 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1311
1312 rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
1313 if (rv != CKR_OK)
1314 {
1315 plog("error in C_SignInit: %s"
1316 , enum_show(&pkcs11_return_names, rv));
1317 return FALSE;
1318 }
1319
1320 rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
1321 , out, &siglen);
1322 if (rv != CKR_OK)
1323 {
1324 plog("error in C_Sign: %s"
1325 , enum_show(&pkcs11_return_names, rv));
1326 return FALSE;
1327 }
1328 }
1329 else if (decrypt_flag)
1330 {
1331 CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
1332 size_t padlen;
1333 u_char *p = out ;
1334
1335 /* PKCS#1 v1.5 8.1 encryption-block formatting */
1336 *p++ = 0x00;
1337 *p++ = 0x01; /* BT (block type) 01 */
1338 padlen = outlen - 3 - inlen;
1339 memset(p, 0xFF, padlen);
1340 p += padlen;
1341 *p++ = 0x00;
1342 memcpy(p, in, inlen);
1343
1344 rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
1345 if (rv != CKR_OK)
1346 {
1347 plog("error in C_DecryptInit: %s"
1348 , enum_show(&pkcs11_return_names, rv));
1349 return FALSE;
1350 }
1351
1352 rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
1353 , out, &siglen);
1354 if (rv != CKR_OK)
1355 {
1356 plog("error in C_Decrypt: %s"
1357 , enum_show(&pkcs11_return_names, rv));
1358 return FALSE;
1359 }
1360 }
1361 else
1362 {
1363 plog("private key has neither sign nor decrypt flag set");
1364 return FALSE;
1365 }
1366
1367 if (siglen > (CK_ULONG)outlen)
1368 {
1369 plog("signature length (%lu) larger than allocated buffer (%d)"
1370 , siglen, (int)outlen);
1371 return FALSE;
1372 }
1373 return TRUE;
1374 #else
1375 return FALSE;
1376 #endif
1377 }
1378
1379 /*
1380 * encrypt data block with an RSA public key
1381 */
1382 bool
1383 scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
1384 , u_char *out, size_t *outlen)
1385 {
1386 #ifdef SMARTCARD
1387 CK_RV rv;
1388 CK_OBJECT_HANDLE object;
1389 CK_ULONG len = (CK_ULONG)(*outlen);
1390 CK_BBOOL encrypt_flag;
1391 CK_ATTRIBUTE attr[] = {
1392 { CKA_MODULUS, NULL_PTR, 0L },
1393 { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
1394 { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
1395 };
1396 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1397
1398 if (!scx_establish_context(sc))
1399 {
1400 scx_release_context(sc);
1401 return FALSE;
1402 }
1403
1404 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
1405 {
1406 plog("unable to find public key with id '%s'", sc->id);
1407 return FALSE;
1408 }
1409
1410 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
1411 if (rv != CKR_OK)
1412 {
1413 plog("couldn't read the public key attributes: %s"
1414 , enum_show(&pkcs11_return_names, rv));
1415 scx_release_context(sc);
1416 return FALSE;
1417 }
1418
1419 if (!encrypt_flag)
1420 {
1421 plog("public key cannot be used for encryption");
1422 scx_release_context(sc);
1423 return FALSE;
1424 }
1425
1426 /* there must be enough space left for the PKCS#1 v1.5 padding */
1427 if (inlen > attr[0].ulValueLen - 11)
1428 {
1429 plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
1430 , (int)inlen, attr[0].ulValueLen - 11);
1431 if (!pkcs11_keep_state)
1432 scx_release_context(sc);
1433 return FALSE;
1434 }
1435
1436 rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
1437
1438 if (rv != CKR_OK)
1439 {
1440 if (rv == CKR_FUNCTION_NOT_SUPPORTED)
1441 {
1442 RSA_public_key_t rsa;
1443 chunk_t plain_text = {in, inlen};
1444 chunk_t cipher_text;
1445
1446 DBG(DBG_CONTROL,
1447 DBG_log("doing RSA encryption in software")
1448 )
1449 attr[0].pValue = alloc_bytes(attr[0].ulValueLen, "modulus");
1450 attr[1].pValue = alloc_bytes(attr[1].ulValueLen, "exponent");
1451
1452 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
1453 if (rv != CKR_OK)
1454 {
1455 plog("couldn't read modulus and public exponent: %s"
1456 , enum_show(&pkcs11_return_names, rv));
1457 pfree(attr[0].pValue);
1458 pfree(attr[1].pValue);
1459 scx_release_context(sc);
1460 return FALSE;
1461 }
1462 rsa.k = attr[0].ulValueLen;
1463 n_to_mpz(&rsa.n, attr[0].pValue, attr[0].ulValueLen);
1464 n_to_mpz(&rsa.e, attr[1].pValue, attr[1].ulValueLen);
1465 pfree(attr[0].pValue);
1466 pfree(attr[1].pValue);
1467
1468 cipher_text = RSA_encrypt(&rsa, plain_text);
1469 free_RSA_public_content(&rsa);
1470 if (cipher_text.ptr == NULL)
1471 {
1472 plog("smartcard input data length is too large");
1473 if (!pkcs11_keep_state)
1474 scx_release_context(sc);
1475 return FALSE;
1476 }
1477
1478 memcpy(out, cipher_text.ptr, cipher_text.len);
1479 *outlen = cipher_text.len;
1480 freeanychunk(cipher_text);
1481 if (!pkcs11_keep_state)
1482 scx_release_context(sc);
1483 return TRUE;
1484 }
1485 else
1486 {
1487 plog("error in C_EncryptInit: %s"
1488 , enum_show(&pkcs11_return_names, rv));
1489 scx_release_context(sc);
1490 return FALSE;
1491 }
1492 }
1493
1494 DBG(DBG_CONTROL,
1495 DBG_log("doing RSA encryption on smartcard")
1496 )
1497 rv = pkcs11_functions->C_Encrypt(sc->session, in, inlen
1498 , out, &len);
1499 if (rv != CKR_OK)
1500 {
1501 plog("error in C_Encrypt: %s"
1502 , enum_show(&pkcs11_return_names, rv));
1503 scx_release_context(sc);
1504 return FALSE;
1505 }
1506 if (!pkcs11_keep_state)
1507 scx_release_context(sc);
1508
1509 *outlen = (size_t)len;
1510 return TRUE;
1511 #else
1512 return FALSE;
1513 #endif
1514 }
1515 /*
1516 * decrypt a data block with an RSA private key
1517 */
1518 bool
1519 scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
1520 , u_char *out, size_t *outlen)
1521 {
1522 #ifdef SMARTCARD
1523 CK_RV rv;
1524 CK_OBJECT_HANDLE object;
1525 CK_ULONG len = (CK_ULONG)(*outlen);
1526 CK_BBOOL decrypt_flag;
1527 CK_ATTRIBUTE attr[] = {
1528 { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
1529 };
1530 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
1531
1532 if (!scx_establish_context(sc) || !scx_login(sc))
1533 {
1534 scx_release_context(sc);
1535 return FALSE;
1536 }
1537
1538 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1539 {
1540 plog("unable to find private key with id '%s'", sc->id);
1541 return FALSE;
1542 }
1543
1544 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
1545 if (rv != CKR_OK)
1546 {
1547 plog("couldn't read the private key attributes: %s"
1548 , enum_show(&pkcs11_return_names, rv));
1549 return FALSE;
1550 }
1551
1552 if (!decrypt_flag)
1553 {
1554 plog("private key cannot be used for decryption");
1555 scx_release_context(sc);
1556 return FALSE;
1557 }
1558
1559 DBG(DBG_CONTROL,
1560 DBG_log("doing RSA decryption on smartcard")
1561 )
1562 rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
1563 if (rv != CKR_OK)
1564 {
1565 plog("error in C_DecryptInit: %s"
1566 , enum_show(&pkcs11_return_names, rv));
1567 scx_release_context(sc);
1568 return FALSE;
1569 }
1570
1571 rv = pkcs11_functions->C_Decrypt(sc->session, in, inlen
1572 , out, &len);
1573 if (rv != CKR_OK)
1574 {
1575 plog("error in C_Decrypt: %s"
1576 , enum_show(&pkcs11_return_names, rv));
1577 scx_release_context(sc);
1578 return FALSE;
1579 }
1580 if (!pkcs11_keep_state)
1581 scx_release_context(sc);
1582
1583 *outlen = (size_t)len;
1584 return TRUE;
1585 #else
1586 return FALSE;
1587 #endif
1588 }
1589
1590 /* receive an encrypted data block via whack,
1591 * decrypt it using a private RSA key and
1592 * return the decrypted data block via whack
1593 */
1594 bool
1595 scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
1596 , const char* keyid, int whackfd)
1597 {
1598 char inbuf[RSA_MAX_OCTETS];
1599 char outbuf[2*RSA_MAX_OCTETS + 1];
1600 size_t outlen = sizeof(inbuf);
1601 size_t inlen;
1602 smartcard_t *sc,*sc_new;
1603
1604 const char *number_slot_id = "";
1605
1606 err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
1607
1608 /* no prefix - use default base */
1609 if (ugh != NULL && inbase == 0)
1610 ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
1611
1612 if (ugh != NULL)
1613 {
1614 plog("format error in smartcard input data: %s", ugh);
1615 return FALSE;
1616 }
1617
1618 if (keyid != NULL)
1619 {
1620 number_slot_id = (strncmp(keyid, SCX_TOKEN, strlen(SCX_TOKEN)) == 0)
1621 ? keyid + strlen(SCX_TOKEN) : keyid;
1622 }
1623
1624 sc_new = scx_parse_number_slot_id(number_slot_id);
1625 sc = scx_add(sc_new);
1626 if (sc == sc_new)
1627 scx_share(sc);
1628
1629 DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
1630 DBG_dump("smartcard input data:\n", inbuf, inlen)
1631 )
1632
1633 if (op == SC_OP_DECRYPT)
1634 {
1635 if (!sc->valid && whackfd != NULL_FD)
1636 scx_get_pin(sc, whackfd);
1637
1638 if (!sc->valid)
1639 {
1640 loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
1641 return FALSE;
1642 }
1643 }
1644
1645 DBG(DBG_CONTROL | DBG_CRYPT,
1646 DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
1647 , (int)sc->slot, sc->id)
1648 )
1649
1650 switch (op)
1651 {
1652 case SC_OP_ENCRYPT:
1653 if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
1654 return FALSE;
1655 break;
1656 case SC_OP_DECRYPT:
1657 if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
1658 return FALSE;
1659 break;
1660 default:
1661 break;
1662 }
1663
1664 DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
1665 DBG_dump("smartcard output data:\n", inbuf, outlen)
1666 )
1667
1668 if (outbase == 0) /* use default base */
1669 outbase = DEFAULT_BASE;
1670
1671 if (outbase == 256) /* ascii plain text */
1672 whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
1673 else
1674 {
1675 outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
1676 if (outlen == 0)
1677 {
1678 plog("error in output format conversion");
1679 return FALSE;
1680 }
1681 whack_log(RC_COMMENT, "%s", outbuf);
1682 }
1683 return TRUE;
1684 }
1685
1686 /*
1687 * get length of RSA key in bytes
1688 */
1689 size_t
1690 scx_get_keylength(smartcard_t *sc)
1691 {
1692 #ifdef SMARTCARD
1693 CK_RV rv;
1694 CK_OBJECT_HANDLE object;
1695 CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
1696
1697 if (!sc->logged_in)
1698 return FALSE;
1699
1700 if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
1701 {
1702 plog("unable to find private key with id '%s'", sc->id);
1703 return FALSE;
1704 }
1705
1706 /* get the length of the private key */
1707 rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
1708 , (CK_ATTRIBUTE_PTR)&attr, 1);
1709 if (rv != CKR_OK)
1710 {
1711 plog("failed to get key length: %s"
1712 , enum_show(&pkcs11_return_names, rv));
1713 return FALSE;
1714 }
1715
1716 return attr[0].ulValueLen; /*Return key length in bytes */
1717 #else
1718 return 0;
1719 #endif
1720 }
1721
1722 /*
1723 * prompt for pin and verify it
1724 */
1725 bool
1726 scx_get_pin(smartcard_t *sc, int whackfd)
1727 {
1728 #ifdef SMARTCARD
1729 char pin[BUF_LEN];
1730 int i, n;
1731
1732 whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
1733 , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
1734
1735 for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
1736 {
1737 if (i > 0)
1738 whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
1739
1740 n = read(whackfd, pin, BUF_LEN);
1741
1742 if (n == -1)
1743 {
1744 whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
1745 return FALSE;
1746 }
1747
1748 if (strlen(pin) == 0)
1749 {
1750 whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
1751 return FALSE;
1752 }
1753
1754 sc->pin.ptr = pin;
1755 sc->pin.len = strlen(pin);
1756
1757 /* verify the pin */
1758 if (scx_verify_pin(sc))
1759 {
1760 clonetochunk(sc->pin, pin, strlen(pin), "pin");
1761 break;
1762 }
1763
1764 /* wrong pin - we try another round */
1765 sc->pin = empty_chunk;
1766 }
1767
1768 if (sc->valid)
1769 whack_log(RC_SUCCESS, "valid PIN");
1770 else
1771 whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
1772 #else
1773 sc->valid = FALSE;
1774 whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
1775 #endif
1776 return sc->valid;
1777 }
1778
1779
1780 /*
1781 * free the pin code
1782 */
1783 void
1784 scx_free_pin(chunk_t *pin)
1785 {
1786 if (pin->ptr != NULL)
1787 {
1788 /* clear pin field in memory */
1789 memset(pin->ptr, '\0', pin->len);
1790 pfree(pin->ptr);
1791 *pin = empty_chunk;
1792 }
1793 }
1794
1795 /*
1796 * frees a smartcard record
1797 */
1798 void
1799 scx_free(smartcard_t *sc)
1800 {
1801 if (sc != NULL)
1802 {
1803 scx_release_context(sc);
1804 pfreeany(sc->id);
1805 pfreeany(sc->label);
1806 scx_free_pin(&sc->pin);
1807 pfree(sc);
1808 }
1809 }
1810
1811 /* release of a smartcard record decreases the count by one
1812 " the record is freed when the counter reaches zero
1813 */
1814 void
1815 scx_release(smartcard_t *sc)
1816 {
1817 if (sc != NULL && --sc->count == 0)
1818 {
1819 smartcard_t **pp = &smartcards;
1820 while (*pp != sc)
1821 pp = &(*pp)->next;
1822 *pp = sc->next;
1823 release_cert(sc->last_cert);
1824 scx_free(sc);
1825 }
1826 }
1827
1828 /*
1829 * compare two smartcard records by comparing their slots and ids
1830 */
1831 static bool
1832 scx_same(smartcard_t *a, smartcard_t *b)
1833 {
1834 if (a->number && b->number)
1835 {
1836 /* same number */
1837 return a->number == b->number;
1838 }
1839 else
1840 {
1841 /* same id and/or same slot */
1842 return (!a->id || (b->id && streq(a->id, b->id)))
1843 && (a->any_slot || b->any_slot || a->slot == b->slot);
1844 }
1845 }
1846
1847 /* for each link pointing to the smartcard record
1848 " increase the count by one
1849 */
1850 void
1851 scx_share(smartcard_t *sc)
1852 {
1853 if (sc != NULL)
1854 sc->count++;
1855 }
1856
1857 /*
1858 * adds a smartcard record to the chained list
1859 */
1860 smartcard_t*
1861 scx_add(smartcard_t *smartcard)
1862 {
1863 smartcard_t *sc = smartcards;
1864 smartcard_t **psc = &smartcards;
1865
1866 while (sc != NULL)
1867 {
1868 if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
1869 {
1870 scx_free(smartcard);
1871 return sc;
1872 }
1873 psc = &sc->next;
1874 sc = sc->next;
1875 }
1876
1877 /* insert new smartcard record at the end of the chain */
1878 *psc = smartcard;
1879 smartcard->number = ++sc_number;
1880 smartcard->count = 1;
1881 DBG(DBG_CONTROL | DBG_PARSING,
1882 DBG_log(" smartcard #%d added", sc_number)
1883 )
1884 return smartcard;
1885 }
1886
1887 /*
1888 * get the smartcard that belongs to an X.509 certificate
1889 */
1890 smartcard_t*
1891 scx_get(x509cert_t *cert)
1892 {
1893 smartcard_t *sc = smartcards;
1894
1895 while (sc != NULL)
1896 {
1897 if (sc->last_cert.u.x509 == cert)
1898 return sc;
1899 sc = sc->next;
1900 }
1901 return NULL;
1902 }
1903
1904 /*
1905 * prints either the slot number or 'any slot'
1906 */
1907 char *
1908 scx_print_slot(smartcard_t *sc, const char *whitespace)
1909 {
1910 char *buf = temporary_cyclic_buffer();
1911
1912 if (sc->any_slot)
1913 snprintf(buf, BUF_LEN, "any slot");
1914 else
1915 snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
1916 return buf;
1917 }
1918
1919 /*
1920 * list all smartcard info records in a chained list
1921 */
1922 void
1923 scx_list(bool utc)
1924 {
1925 smartcard_t *sc = smartcards;
1926
1927 if (sc != NULL)
1928 {
1929 whack_log(RC_COMMENT, " ");
1930 whack_log(RC_COMMENT, "List of Smartcard Objects:");
1931 whack_log(RC_COMMENT, " ");
1932 }
1933
1934 while (sc != NULL)
1935 {
1936 whack_log(RC_COMMENT, "%s, #%d, count: %d"
1937 , timetoa(&sc->last_load, utc)
1938 , sc->number
1939 , sc->count);
1940 whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
1941 , scx_print_slot(sc, " ")
1942 , sc->session_opened? "opened" : "closed"
1943 , sc->logged_in? "in" : "out"
1944 , sc->pinpad? "pin pad"
1945 : ((sc->pin.ptr == NULL)? "no pin"
1946 : sc->valid? "valid pin" : "invalid pin"));
1947 if (sc->id != NULL)
1948 whack_log(RC_COMMENT, " id: %s", sc->id);
1949 if (sc->label != NULL)
1950 whack_log(RC_COMMENT, " label: '%s'", sc->label);
1951 if (sc->last_cert.type == CERT_X509_SIGNATURE)
1952 {
1953 char buf[BUF_LEN];
1954
1955 dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
1956 whack_log(RC_COMMENT, " subject: '%s'", buf);
1957 }
1958 sc = sc->next;
1959 }
1960 }