f908219ed268dc2db312522fc95fec3532caec47
[strongswan.git] / src / libcharon / plugins / stroke / stroke_cred.c
1 /*
2 * Copyright (C) 2008-2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <limits.h>
20 #include <fcntl.h>
21 #include <errno.h>
22 #include <unistd.h>
23
24 #ifdef HAVE_GLOB_H
25 #include <glob.h>
26 #endif
27
28 #include "stroke_cred.h"
29
30 #include <credentials/certificates/x509.h>
31 #include <credentials/certificates/crl.h>
32 #include <credentials/certificates/ac.h>
33 #include <credentials/containers/pkcs12.h>
34 #include <credentials/sets/mem_cred.h>
35 #include <credentials/sets/callback_cred.h>
36 #include <collections/linked_list.h>
37 #include <utils/lexparser.h>
38 #include <threading/rwlock.h>
39 #include <daemon.h>
40
41 /* configuration directories and files */
42 #define CONFIG_DIR IPSEC_CONFDIR
43 #define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
44 #define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
45 #define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
46 #define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
47 #define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
48 #define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
49 #define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
50 #define CRL_DIR IPSEC_D_DIR "/crls"
51 #define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
52
53 #define MAX_SECRETS_RECURSION 10
54
55 typedef struct private_stroke_cred_t private_stroke_cred_t;
56
57 /**
58 * private data of stroke_cred
59 */
60 struct private_stroke_cred_t {
61
62 /**
63 * public functions
64 */
65 stroke_cred_t public;
66
67 /**
68 * credentials
69 */
70 mem_cred_t *creds;
71
72 /**
73 * ignore missing CA basic constraint (i.e. treat all certificates in
74 * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
75 */
76 bool force_ca_cert;
77
78 /**
79 * cache CRLs to disk?
80 */
81 bool cachecrl;
82 };
83
84 /** Length of smartcard specifier parts (module, keyid) */
85 #define SC_PART_LEN 128
86
87 /**
88 * Kind of smartcard specifier token
89 */
90 typedef enum {
91 SC_FORMAT_SLOT_MODULE_KEYID,
92 SC_FORMAT_SLOT_KEYID,
93 SC_FORMAT_KEYID,
94 SC_FORMAT_INVALID,
95 } smartcard_format_t;
96
97 /**
98 * Parse a smartcard specifier token
99 */
100 static smartcard_format_t parse_smartcard(char *smartcard, u_int *slot,
101 char *module, char *keyid)
102 {
103 /* The token has one of the following three formats:
104 * - %smartcard<slot>@<module>:<keyid>
105 * - %smartcard<slot>:<keyid>
106 * - %smartcard:<keyid>
107 */
108 char buf[2 * SC_PART_LEN], *pos;
109
110 if (sscanf(smartcard, "%%smartcard%u@%255s", slot, buf) == 2)
111 {
112 pos = strchr(buf, ':');
113 if (!pos)
114 {
115 return SC_FORMAT_INVALID;
116 }
117 *pos++ = '\0';
118 snprintf(module, SC_PART_LEN, "%s", buf);
119 snprintf(keyid, SC_PART_LEN, "%s", pos);
120 return SC_FORMAT_SLOT_MODULE_KEYID;
121 }
122 if (sscanf(smartcard, "%%smartcard%u:%127s", slot, keyid) == 2)
123 {
124 return SC_FORMAT_SLOT_KEYID;
125 }
126 if (sscanf(smartcard, "%%smartcard:%127s", keyid) == 1)
127 {
128 return SC_FORMAT_KEYID;
129 }
130 return SC_FORMAT_INVALID;
131 }
132
133 /**
134 * Load a credential from a smartcard
135 */
136 static certificate_t *load_from_smartcard(smartcard_format_t format,
137 u_int slot, char *module, char *keyid,
138 credential_type_t type, int subtype)
139 {
140 chunk_t chunk;
141 void *cred;
142
143 chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
144 switch (format)
145 {
146 case SC_FORMAT_SLOT_MODULE_KEYID:
147 cred = lib->creds->create(lib->creds, type, subtype,
148 BUILD_PKCS11_SLOT, slot,
149 BUILD_PKCS11_MODULE, module,
150 BUILD_PKCS11_KEYID, chunk, BUILD_END);
151 break;
152 case SC_FORMAT_SLOT_KEYID:
153 cred = lib->creds->create(lib->creds, type, subtype,
154 BUILD_PKCS11_SLOT, slot,
155 BUILD_PKCS11_KEYID, chunk, BUILD_END);
156 break;
157 case SC_FORMAT_KEYID:
158 cred = lib->creds->create(lib->creds, type, subtype,
159 BUILD_PKCS11_KEYID, chunk, BUILD_END);
160 break;
161 default:
162 cred = NULL;
163 break;
164 }
165 free(chunk.ptr);
166
167 return cred;
168 }
169
170 METHOD(stroke_cred_t, load_ca, certificate_t*,
171 private_stroke_cred_t *this, char *filename)
172 {
173 certificate_t *cert = NULL;
174 char path[PATH_MAX];
175
176 if (strpfx(filename, "%smartcard"))
177 {
178 smartcard_format_t format;
179 char module[SC_PART_LEN], keyid[SC_PART_LEN];
180 u_int slot;
181
182 format = parse_smartcard(filename, &slot, module, keyid);
183 if (format != SC_FORMAT_INVALID)
184 {
185 cert = (certificate_t*)load_from_smartcard(format,
186 slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
187 }
188 }
189 else
190 {
191 if (*filename == '/')
192 {
193 snprintf(path, sizeof(path), "%s", filename);
194 }
195 else
196 {
197 snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
198 }
199
200 if (this->force_ca_cert)
201 { /* we treat this certificate as a CA certificate even if it has no
202 * CA basic constraint */
203 cert = lib->creds->create(lib->creds,
204 CRED_CERTIFICATE, CERT_X509,
205 BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
206 BUILD_END);
207 }
208 else
209 {
210 cert = lib->creds->create(lib->creds,
211 CRED_CERTIFICATE, CERT_X509,
212 BUILD_FROM_FILE, path,
213 BUILD_END);
214 }
215 }
216 if (cert)
217 {
218 x509_t *x509 = (x509_t*)cert;
219
220 if (!(x509->get_flags(x509) & X509_CA))
221 {
222 DBG1(DBG_CFG, " ca certificate \"%Y\" misses ca basic constraint, "
223 "discarded", cert->get_subject(cert));
224 cert->destroy(cert);
225 return NULL;
226 }
227 DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
228 cert->get_subject(cert), filename);
229 return this->creds->add_cert_ref(this->creds, TRUE, cert);
230 }
231 return NULL;
232 }
233
234 METHOD(stroke_cred_t, load_peer, certificate_t*,
235 private_stroke_cred_t *this, char *filename)
236 {
237 certificate_t *cert = NULL;
238 char path[PATH_MAX];
239
240 if (strpfx(filename, "%smartcard"))
241 {
242 smartcard_format_t format;
243 char module[SC_PART_LEN], keyid[SC_PART_LEN];
244 u_int slot;
245
246 format = parse_smartcard(filename, &slot, module, keyid);
247 if (format != SC_FORMAT_INVALID)
248 {
249 cert = (certificate_t*)load_from_smartcard(format,
250 slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
251 }
252 }
253 else
254 {
255 if (*filename == '/')
256 {
257 snprintf(path, sizeof(path), "%s", filename);
258 }
259 else
260 {
261 snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
262 }
263
264 cert = lib->creds->create(lib->creds,
265 CRED_CERTIFICATE, CERT_ANY,
266 BUILD_FROM_FILE, path,
267 BUILD_END);
268 }
269 if (cert)
270 {
271 cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
272 DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
273 cert->get_subject(cert), filename);
274 return cert;
275 }
276 DBG1(DBG_CFG, " loading certificate from '%s' failed", filename);
277 return NULL;
278 }
279
280 METHOD(stroke_cred_t, load_pubkey, certificate_t*,
281 private_stroke_cred_t *this, char *filename, identification_t *identity)
282 {
283 certificate_t *cert;
284 public_key_t *key;
285 char path[PATH_MAX];
286 builder_part_t build_part;
287 key_type_t type = KEY_ANY;
288
289 if (streq(filename, "%dns"))
290 {
291 return NULL;
292 }
293 if (strncaseeq(filename, "dns:", 4))
294 { /* RFC 3110 format */
295 build_part = BUILD_BLOB_DNSKEY;
296 /* not a complete RR, only RSA supported */
297 type = KEY_RSA;
298 filename += 4;
299 }
300 else if (strncaseeq(filename, "ssh:", 4))
301 { /* SSH key */
302 build_part = BUILD_BLOB_SSHKEY;
303 filename += 4;
304 }
305 else
306 { /* try PKCS#1 by default */
307 build_part = BUILD_BLOB_ASN1_DER;
308 }
309 if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2))
310 {
311 chunk_t printable_key, raw_key;
312
313 printable_key = chunk_create(filename + 2, strlen(filename) - 2);
314 raw_key = strncaseeq(filename, "0x", 2) ?
315 chunk_from_hex(printable_key, NULL) :
316 chunk_from_base64(printable_key, NULL);
317 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
318 build_part, raw_key, BUILD_END);
319 chunk_free(&raw_key);
320 if (key)
321 {
322 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
323 CERT_TRUSTED_PUBKEY,
324 BUILD_PUBLIC_KEY, key,
325 BUILD_SUBJECT, identity,
326 BUILD_END);
327 type = key->get_type(key);
328 key->destroy(key);
329 if (cert)
330 {
331 cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
332 DBG1(DBG_CFG, " loaded %N public key for \"%Y\"",
333 key_type_names, type, identity);
334 return cert;
335 }
336 }
337 DBG1(DBG_CFG, " loading public key for \"%Y\" failed", identity);
338 }
339 else
340 {
341 if (*filename == '/')
342 {
343 snprintf(path, sizeof(path), "%s", filename);
344 }
345 else
346 {
347 snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
348 }
349
350 cert = lib->creds->create(lib->creds,
351 CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
352 BUILD_FROM_FILE, path,
353 BUILD_SUBJECT, identity,
354 BUILD_END);
355 if (cert)
356 {
357 cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
358 key = cert->get_public_key(cert);
359 type = key->get_type(key);
360 key->destroy(key);
361 DBG1(DBG_CFG, " loaded %N public key for \"%Y\" from '%s'",
362 key_type_names, type, identity, filename);
363 return cert;
364 }
365 DBG1(DBG_CFG, " loading public key for \"%Y\" from '%s' failed",
366 identity, filename);
367 }
368 return NULL;
369 }
370
371 /**
372 * load trusted certificates from a directory
373 */
374 static void load_certdir(private_stroke_cred_t *this, char *path,
375 certificate_type_t type, x509_flag_t flag)
376 {
377 struct stat st;
378 char *file;
379
380 enumerator_t *enumerator = enumerator_create_directory(path);
381
382 if (!enumerator)
383 {
384 DBG1(DBG_CFG, " reading directory failed");
385 return;
386 }
387
388 while (enumerator->enumerate(enumerator, NULL, &file, &st))
389 {
390 certificate_t *cert;
391
392 if (!S_ISREG(st.st_mode))
393 {
394 /* skip special file */
395 continue;
396 }
397 switch (type)
398 {
399 case CERT_X509:
400 if (flag & X509_CA)
401 {
402 if (this->force_ca_cert)
403 { /* treat this certificate as CA cert even it has no
404 * CA basic constraint */
405 cert = lib->creds->create(lib->creds,
406 CRED_CERTIFICATE, CERT_X509,
407 BUILD_FROM_FILE, file, BUILD_X509_FLAG,
408 X509_CA, BUILD_END);
409 }
410 else
411 {
412 cert = lib->creds->create(lib->creds,
413 CRED_CERTIFICATE, CERT_X509,
414 BUILD_FROM_FILE, file, BUILD_END);
415 }
416 if (cert)
417 {
418 x509_t *x509 = (x509_t*)cert;
419
420 if (!(x509->get_flags(x509) & X509_CA))
421 {
422 DBG1(DBG_CFG, " ca certificate \"%Y\" lacks "
423 "ca basic constraint, discarded",
424 cert->get_subject(cert));
425 cert->destroy(cert);
426 cert = NULL;
427 }
428 else
429 {
430 DBG1(DBG_CFG, " loaded ca certificate \"%Y\" "
431 "from '%s'", cert->get_subject(cert), file);
432 }
433 }
434 else
435 {
436 DBG1(DBG_CFG, " loading ca certificate from '%s' "
437 "failed", file);
438 }
439 }
440 else
441 { /* for all other flags, we add them to the certificate. */
442 cert = lib->creds->create(lib->creds,
443 CRED_CERTIFICATE, CERT_X509,
444 BUILD_FROM_FILE, file,
445 BUILD_X509_FLAG, flag, BUILD_END);
446 if (cert)
447 {
448 DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
449 cert->get_subject(cert), file);
450 }
451 else
452 {
453 DBG1(DBG_CFG, " loading certificate from '%s' "
454 "failed", file);
455 }
456 }
457 if (cert)
458 {
459 this->creds->add_cert(this->creds, TRUE, cert);
460 }
461 break;
462 case CERT_X509_CRL:
463 cert = lib->creds->create(lib->creds,
464 CRED_CERTIFICATE, CERT_X509_CRL,
465 BUILD_FROM_FILE, file,
466 BUILD_END);
467 if (cert)
468 {
469 this->creds->add_crl(this->creds, (crl_t*)cert);
470 DBG1(DBG_CFG, " loaded crl from '%s'", file);
471 }
472 else
473 {
474 DBG1(DBG_CFG, " loading crl from '%s' failed", file);
475 }
476 break;
477 case CERT_X509_AC:
478 cert = lib->creds->create(lib->creds,
479 CRED_CERTIFICATE, CERT_X509_AC,
480 BUILD_FROM_FILE, file,
481 BUILD_END);
482 if (cert)
483 {
484 this->creds->add_cert(this->creds, FALSE, cert);
485 DBG1(DBG_CFG, " loaded attribute certificate from '%s'",
486 file);
487 }
488 else
489 {
490 DBG1(DBG_CFG, " loading attribute certificate from '%s' "
491 "failed", file);
492 }
493 break;
494 default:
495 break;
496 }
497 }
498 enumerator->destroy(enumerator);
499 }
500
501 METHOD(stroke_cred_t, cache_cert, void,
502 private_stroke_cred_t *this, certificate_t *cert)
503 {
504 if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
505 {
506 /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
507 crl_t *crl = (crl_t*)cert;
508
509 cert->get_ref(cert);
510 if (this->creds->add_crl(this->creds, crl))
511 {
512 char buf[BUF_LEN];
513 chunk_t chunk, hex;
514
515 chunk = crl->get_authKeyIdentifier(crl);
516 hex = chunk_to_hex(chunk, NULL, FALSE);
517 snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex.ptr);
518 free(hex.ptr);
519
520 if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk))
521 {
522 if (chunk_write(chunk, buf, 022, TRUE))
523 {
524 DBG1(DBG_CFG, " written crl file '%s' (%d bytes)",
525 buf, chunk.len);
526 }
527 else
528 {
529 DBG1(DBG_CFG, " writing crl file '%s' failed: %s",
530 buf, strerror(errno));
531 }
532 free(chunk.ptr);
533 }
534 }
535 }
536 }
537
538 METHOD(stroke_cred_t, cachecrl, void,
539 private_stroke_cred_t *this, bool enabled)
540 {
541 DBG1(DBG_CFG, "crl caching to %s %s",
542 CRL_DIR, enabled ? "enabled" : "disabled");
543 this->cachecrl = enabled;
544 }
545
546
547 /**
548 * Convert a string of characters into a binary secret
549 * A string between single or double quotes is treated as ASCII characters
550 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
551 */
552 static err_t extract_secret(chunk_t *secret, chunk_t *line)
553 {
554 chunk_t raw_secret;
555 char delimiter = ' ';
556 bool quotes = FALSE;
557
558 if (!eat_whitespace(line))
559 {
560 return "missing secret";
561 }
562
563 if (*line->ptr == '\'' || *line->ptr == '"')
564 {
565 quotes = TRUE;
566 delimiter = *line->ptr;
567 line->ptr++; line->len--;
568 }
569
570 if (!extract_token(&raw_secret, delimiter, line))
571 {
572 if (delimiter == ' ')
573 {
574 raw_secret = *line;
575 }
576 else
577 {
578 return "missing second delimiter";
579 }
580 }
581
582 if (quotes)
583 {
584 /* treat as an ASCII string */
585 *secret = chunk_clone(raw_secret);
586 return NULL;
587 }
588 /* treat 0x as hex, 0s as base64 */
589 if (raw_secret.len > 2)
590 {
591 if (strncasecmp("0x", raw_secret.ptr, 2) == 0)
592 {
593 *secret = chunk_from_hex(chunk_skip(raw_secret, 2), NULL);
594 return NULL;
595 }
596 if (strncasecmp("0s", raw_secret.ptr, 2) == 0)
597 {
598 *secret = chunk_from_base64(chunk_skip(raw_secret, 2), NULL);
599 return NULL;
600 }
601 }
602 *secret = chunk_clone(raw_secret);
603 return NULL;
604 }
605
606 /**
607 * Data for passphrase callback
608 */
609 typedef struct {
610 /** cached passphrases */
611 mem_cred_t *cache;
612 /** socket we use for prompting */
613 FILE *prompt;
614 /** type of secret to unlock */
615 int type;
616 /** private key file */
617 char *path;
618 /** number of tries */
619 int try;
620 } passphrase_cb_data_t;
621
622 /**
623 * Callback function to receive passphrases
624 */
625 static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
626 shared_key_type_t type, identification_t *me,
627 identification_t *other, id_match_t *match_me,
628 id_match_t *match_other)
629 {
630 static const int max_tries = 3;
631 shared_key_t *shared;
632 chunk_t secret;
633 char buf[256];
634
635 if (type != SHARED_ANY && type != SHARED_PRIVATE_KEY_PASS)
636 {
637 return NULL;
638 }
639
640 data->try++;
641 if (data->try > max_tries + 1)
642 { /* another builder might call this after we gave up, fail silently */
643 return NULL;
644 }
645 if (data->try > max_tries)
646 {
647 fprintf(data->prompt, "Passphrase invalid, giving up.\n");
648 return NULL;
649 }
650 if (data->try > 1)
651 {
652 fprintf(data->prompt, "Passphrase invalid!\n");
653 }
654 fprintf(data->prompt, "%s '%s' is encrypted.\n",
655 data->type == CRED_PRIVATE_KEY ? "Private key" : "PKCS#12 file",
656 data->path);
657 fprintf(data->prompt, "Passphrase:\n");
658 if (fgets(buf, sizeof(buf), data->prompt))
659 {
660 secret = chunk_create(buf, strlen(buf));
661 if (secret.len > 1)
662 { /* trim appended \n */
663 secret.len--;
664 if (match_me)
665 {
666 *match_me = ID_MATCH_PERFECT;
667 }
668 if (match_other)
669 {
670 *match_other = ID_MATCH_NONE;
671 }
672 shared = shared_key_create(SHARED_PRIVATE_KEY_PASS,
673 chunk_clone(secret));
674 data->cache->add_shared(data->cache, shared->get_ref(shared), NULL);
675 return shared;
676 }
677 }
678 return NULL;
679 }
680
681 /**
682 * Data for PIN callback
683 */
684 typedef struct {
685 /** socket we use for prompting */
686 FILE *prompt;
687 /** card label */
688 char *card;
689 /** card keyid */
690 chunk_t keyid;
691 /** number of tries */
692 int try;
693 } pin_cb_data_t;
694
695 /**
696 * Callback function to receive PINs
697 */
698 static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type,
699 identification_t *me, identification_t *other,
700 id_match_t *match_me, id_match_t *match_other)
701 {
702 chunk_t secret;
703 char buf[256];
704
705 if (type != SHARED_ANY && type != SHARED_PIN)
706 {
707 return NULL;
708 }
709
710 if (!me || !chunk_equals(me->get_encoding(me), data->keyid))
711 {
712 return NULL;
713 }
714
715 data->try++;
716 if (data->try > 1)
717 {
718 fprintf(data->prompt, "PIN invalid, aborting.\n");
719 return NULL;
720 }
721 fprintf(data->prompt, "Login to '%s' required\n", data->card);
722 fprintf(data->prompt, "PIN:\n");
723 if (fgets(buf, sizeof(buf), data->prompt))
724 {
725 secret = chunk_create(buf, strlen(buf));
726 if (secret.len > 1)
727 { /* trim appended \n */
728 secret.len--;
729 if (match_me)
730 {
731 *match_me = ID_MATCH_PERFECT;
732 }
733 if (match_other)
734 {
735 *match_other = ID_MATCH_NONE;
736 }
737 return shared_key_create(SHARED_PIN, chunk_clone(secret));
738 }
739 }
740 return NULL;
741 }
742
743 /**
744 * Load a smartcard with a PIN
745 */
746 static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
747 FILE *prompt)
748 {
749 chunk_t sc = chunk_empty, secret = chunk_empty;
750 char smartcard[BUF_LEN], keyid[SC_PART_LEN], module[SC_PART_LEN];
751 private_key_t *key = NULL;
752 u_int slot;
753 chunk_t chunk;
754 shared_key_t *shared;
755 identification_t *id;
756 mem_cred_t *mem = NULL;
757 callback_cred_t *cb = NULL;
758 pin_cb_data_t pin_data;
759 smartcard_format_t format;
760
761 err_t ugh = extract_value(&sc, &line);
762
763 if (ugh != NULL)
764 {
765 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
766 return FALSE;
767 }
768 if (sc.len == 0)
769 {
770 DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr);
771 return FALSE;
772 }
773 snprintf(smartcard, sizeof(smartcard), "%.*s", (int)sc.len, sc.ptr);
774 smartcard[sizeof(smartcard) - 1] = '\0';
775
776 format = parse_smartcard(smartcard, &slot, module, keyid);
777 if (format == SC_FORMAT_INVALID)
778 {
779 DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
780 " supported or invalid", line_nr);
781 return FALSE;
782 }
783
784 if (!eat_whitespace(&line))
785 {
786 DBG1(DBG_CFG, "line %d: expected PIN", line_nr);
787 return FALSE;
788 }
789 ugh = extract_secret(&secret, &line);
790 if (ugh != NULL)
791 {
792 DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh);
793 return FALSE;
794 }
795
796 chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
797 if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
798 {
799 free(secret.ptr);
800 if (!prompt)
801 { /* no IO channel to prompt, skip */
802 chunk_clear(&chunk);
803 return TRUE;
804 }
805 /* use callback credential set to prompt for the pin */
806 pin_data.prompt = prompt;
807 pin_data.card = smartcard;
808 pin_data.keyid = chunk;
809 pin_data.try = 0;
810 cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
811 lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
812 }
813 else
814 {
815 /* provide our pin in a temporary credential set */
816 shared = shared_key_create(SHARED_PIN, secret);
817 id = identification_create_from_encoding(ID_KEY_ID, chunk);
818 mem = mem_cred_create();
819 mem->add_shared(mem, shared, id, NULL);
820 lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
821 }
822
823 /* unlock: smartcard needs the pin and potentially calls public set */
824 key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
825 CRED_PRIVATE_KEY, KEY_ANY);
826 if (mem)
827 {
828 lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
829 mem->destroy(mem);
830 }
831 if (cb)
832 {
833 lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
834 cb->destroy(cb);
835 }
836 chunk_clear(&chunk);
837
838 if (key)
839 {
840 DBG1(DBG_CFG, " loaded private key from %.*s", (int)sc.len, sc.ptr);
841 secrets->add_key(secrets, key);
842 }
843 return TRUE;
844 }
845
846 /**
847 * Load a private key or PKCS#12 container from a file
848 */
849 static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
850 char *path, int type, int subtype,
851 void **result)
852 {
853 chunk_t filename;
854 chunk_t secret = chunk_empty;
855
856 err_t ugh = extract_value(&filename, &line);
857
858 if (ugh != NULL)
859 {
860 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
861 return FALSE;
862 }
863 if (filename.len == 0)
864 {
865 DBG1(DBG_CFG, "line %d: empty filename", line_nr);
866 return FALSE;
867 }
868 if (*filename.ptr == '/')
869 {
870 /* absolute path name */
871 snprintf(path, PATH_MAX, "%.*s", (int)filename.len, filename.ptr);
872 }
873 else
874 {
875 /* relative path name */
876 snprintf(path, PATH_MAX, "%s/%.*s", PRIVATE_KEY_DIR,
877 (int)filename.len, filename.ptr);
878 }
879
880 /* check for optional passphrase */
881 if (eat_whitespace(&line))
882 {
883 ugh = extract_secret(&secret, &line);
884 if (ugh != NULL)
885 {
886 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
887 return FALSE;
888 }
889 }
890 if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
891 {
892 callback_cred_t *cb;
893 passphrase_cb_data_t pp_data = {
894 .prompt = prompt,
895 .type = type,
896 .path = path,
897 .try = 0,
898 };
899
900 free(secret.ptr);
901 if (!prompt)
902 {
903 *result = NULL;
904 return TRUE;
905 }
906 /* add cache first so if valid passphrases are needed multiple times
907 * the callback is not called anymore */
908 pp_data.cache = mem_cred_create();
909 lib->credmgr->add_local_set(lib->credmgr, &pp_data.cache->set, FALSE);
910 /* use callback credential set to prompt for the passphrase */
911 cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
912 lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
913
914 *result = lib->creds->create(lib->creds, type, subtype,
915 BUILD_FROM_FILE, path, BUILD_END);
916
917 lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
918 cb->destroy(cb);
919 lib->credmgr->remove_local_set(lib->credmgr, &pp_data.cache->set);
920 pp_data.cache->destroy(pp_data.cache);
921 }
922 else
923 {
924 mem_cred_t *mem = NULL;
925 shared_key_t *shared;
926
927 /* provide our pin in a temporary credential set */
928 shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret);
929 mem = mem_cred_create();
930 mem->add_shared(mem, shared, NULL);
931 if (eat_whitespace(&line))
932 { /* if there is a second passphrase add that too, could be needed for
933 * PKCS#12 files using different passwords for MAC and encryption */
934 ugh = extract_secret(&secret, &line);
935 if (ugh != NULL)
936 {
937 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
938 mem->destroy(mem);
939 return FALSE;
940 }
941 shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret);
942 mem->add_shared(mem, shared, NULL);
943 }
944 lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
945
946 *result = lib->creds->create(lib->creds, type, subtype,
947 BUILD_FROM_FILE, path, BUILD_END);
948
949 lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
950 mem->destroy(mem);
951 }
952 return TRUE;
953 }
954
955 /**
956 * Load a private key
957 */
958 static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
959 FILE *prompt, key_type_t key_type)
960 {
961 char path[PATH_MAX];
962 private_key_t *key;
963
964 if (!load_from_file(line, line_nr, prompt, path, CRED_PRIVATE_KEY,
965 key_type, (void**)&key))
966 {
967 return FALSE;
968 }
969 if (key)
970 {
971 DBG1(DBG_CFG, " loaded %N private key from '%s'",
972 key_type_names, key->get_type(key), path);
973 secrets->add_key(secrets, key);
974 }
975 else
976 {
977 DBG1(DBG_CFG, " loading private key from '%s' failed", path);
978 }
979 return TRUE;
980 }
981
982 /**
983 * Load a PKCS#12 container
984 */
985 static bool load_pkcs12(private_stroke_cred_t *this, mem_cred_t *secrets,
986 chunk_t line, int line_nr, FILE *prompt)
987 {
988 enumerator_t *enumerator;
989 char path[PATH_MAX];
990 certificate_t *cert;
991 private_key_t *key;
992 pkcs12_t *pkcs12;
993
994 if (!load_from_file(line, line_nr, prompt, path, CRED_CONTAINER,
995 CONTAINER_PKCS12, (void**)&pkcs12))
996 {
997 return FALSE;
998 }
999 if (!pkcs12)
1000 {
1001 DBG1(DBG_CFG, " loading credentials from '%s' failed", path);
1002 return TRUE;
1003 }
1004 enumerator = pkcs12->create_cert_enumerator(pkcs12);
1005 while (enumerator->enumerate(enumerator, &cert))
1006 {
1007 x509_t *x509 = (x509_t*)cert;
1008
1009 if (x509->get_flags(x509) & X509_CA)
1010 {
1011 DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
1012 cert->get_subject(cert), path);
1013 }
1014 else
1015 {
1016 DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
1017 cert->get_subject(cert), path);
1018 }
1019 this->creds->add_cert(this->creds, TRUE, cert->get_ref(cert));
1020 }
1021 enumerator->destroy(enumerator);
1022 enumerator = pkcs12->create_key_enumerator(pkcs12);
1023 while (enumerator->enumerate(enumerator, &key))
1024 {
1025 DBG1(DBG_CFG, " loaded %N private key from '%s'",
1026 key_type_names, key->get_type(key), path);
1027 secrets->add_key(secrets, key->get_ref(key));
1028 }
1029 enumerator->destroy(enumerator);
1030 pkcs12->container.destroy(&pkcs12->container);
1031 return TRUE;
1032 }
1033
1034 /**
1035 * Load a shared key
1036 */
1037 static bool load_shared(mem_cred_t *secrets, chunk_t line, int line_nr,
1038 shared_key_type_t type, chunk_t ids)
1039 {
1040 shared_key_t *shared_key;
1041 linked_list_t *owners;
1042 chunk_t secret = chunk_empty;
1043 bool any = TRUE;
1044
1045 err_t ugh = extract_secret(&secret, &line);
1046 if (ugh != NULL)
1047 {
1048 DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
1049 return FALSE;
1050 }
1051 shared_key = shared_key_create(type, secret);
1052 DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type,
1053 ids.len > 0 ? (char*)ids.ptr : "%any");
1054 DBG4(DBG_CFG, " secret: %#B", &secret);
1055
1056 owners = linked_list_create();
1057 while (ids.len > 0)
1058 {
1059 chunk_t id;
1060 identification_t *peer_id;
1061
1062 ugh = extract_value(&id, &ids);
1063 if (ugh != NULL)
1064 {
1065 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1066 shared_key->destroy(shared_key);
1067 owners->destroy_offset(owners, offsetof(identification_t, destroy));
1068 return FALSE;
1069 }
1070 if (id.len == 0)
1071 {
1072 continue;
1073 }
1074
1075 /* NULL terminate the ID string */
1076 *(id.ptr + id.len) = '\0';
1077 peer_id = identification_create_from_string(id.ptr);
1078 if (peer_id->get_type(peer_id) == ID_ANY)
1079 {
1080 peer_id->destroy(peer_id);
1081 continue;
1082 }
1083
1084 owners->insert_last(owners, peer_id);
1085 any = FALSE;
1086 }
1087 if (any)
1088 {
1089 owners->insert_last(owners,
1090 identification_create_from_encoding(ID_ANY, chunk_empty));
1091 }
1092 secrets->add_shared_list(secrets, shared_key, owners);
1093 return TRUE;
1094 }
1095
1096 /**
1097 * reload ipsec.secrets
1098 */
1099 static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
1100 char *file, int level, FILE *prompt)
1101 {
1102 int line_nr = 0;
1103 chunk_t *src, line;
1104
1105 DBG1(DBG_CFG, "loading secrets from '%s'", file);
1106 src = chunk_map(file, FALSE);
1107 if (!src)
1108 {
1109 DBG1(DBG_CFG, "opening secrets file '%s' failed: %s", file,
1110 strerror(errno));
1111 return;
1112 }
1113
1114 if (!secrets)
1115 {
1116 secrets = mem_cred_create();
1117 }
1118
1119 while (fetchline(src, &line))
1120 {
1121 chunk_t ids, token;
1122 shared_key_type_t type;
1123
1124 line_nr++;
1125
1126 if (!eat_whitespace(&line))
1127 {
1128 continue;
1129 }
1130 if (line.len > strlen("include ") && strpfx(line.ptr, "include "))
1131 {
1132 char **expanded, *dir, pattern[PATH_MAX];
1133 u_char *pos;
1134
1135 if (level > MAX_SECRETS_RECURSION)
1136 {
1137 DBG1(DBG_CFG, "maximum level of %d includes reached, ignored",
1138 MAX_SECRETS_RECURSION);
1139 continue;
1140 }
1141 /* terminate filename by space */
1142 line = chunk_skip(line, strlen("include "));
1143 pos = memchr(line.ptr, ' ', line.len);
1144 if (pos)
1145 {
1146 line.len = pos - line.ptr;
1147 }
1148 if (line.len && line.ptr[0] == '/')
1149 {
1150 if (line.len + 1 > sizeof(pattern))
1151 {
1152 DBG1(DBG_CFG, "include pattern too long, ignored");
1153 continue;
1154 }
1155 snprintf(pattern, sizeof(pattern), "%.*s",
1156 (int)line.len, line.ptr);
1157 }
1158 else
1159 { /* use directory of current file if relative */
1160 dir = path_dirname(file);
1161
1162 if (line.len + 1 + strlen(dir) + 1 > sizeof(pattern))
1163 {
1164 DBG1(DBG_CFG, "include pattern too long, ignored");
1165 free(dir);
1166 continue;
1167 }
1168 snprintf(pattern, sizeof(pattern), "%s/%.*s",
1169 dir, (int)line.len, line.ptr);
1170 free(dir);
1171 }
1172 #ifdef HAVE_GLOB_H
1173 {
1174 glob_t buf;
1175 if (glob(pattern, GLOB_ERR, NULL, &buf) != 0)
1176 {
1177 DBG1(DBG_CFG, "expanding file expression '%s' failed",
1178 pattern);
1179 }
1180 else
1181 {
1182 for (expanded = buf.gl_pathv; *expanded != NULL; expanded++)
1183 {
1184 load_secrets(this, secrets, *expanded, level + 1,
1185 prompt);
1186 }
1187 }
1188 globfree(&buf);
1189 }
1190 #else /* HAVE_GLOB_H */
1191 /* if glob(3) is not available, try to load pattern directly */
1192 load_secrets(this, secrets, pattern, level + 1, prompt);
1193 #endif /* HAVE_GLOB_H */
1194 continue;
1195 }
1196
1197 if (line.len > 2 && strpfx(line.ptr, ": "))
1198 {
1199 /* no ids, skip the ':' */
1200 ids = chunk_empty;
1201 line.ptr++;
1202 line.len--;
1203 }
1204 else if (extract_token_str(&ids, " : ", &line))
1205 {
1206 /* NULL terminate the extracted id string */
1207 *(ids.ptr + ids.len) = '\0';
1208 }
1209 else
1210 {
1211 DBG1(DBG_CFG, "line %d: missing ' : ' separator", line_nr);
1212 break;
1213 }
1214
1215 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
1216 {
1217 DBG1(DBG_CFG, "line %d: missing token", line_nr);
1218 break;
1219 }
1220 if (match("RSA", &token) || match("ECDSA", &token))
1221 {
1222 if (!load_private(secrets, line, line_nr, prompt,
1223 match("RSA", &token) ? KEY_RSA : KEY_ECDSA))
1224 {
1225 break;
1226 }
1227 }
1228 else if (match("P12", &token))
1229 {
1230 if (!load_pkcs12(this, secrets, line, line_nr, prompt))
1231 {
1232 break;
1233 }
1234 }
1235 else if (match("PIN", &token))
1236 {
1237 if (!load_pin(secrets, line, line_nr, prompt))
1238 {
1239 break;
1240 }
1241 }
1242 else if ((match("PSK", &token) && (type = SHARED_IKE)) ||
1243 (match("EAP", &token) && (type = SHARED_EAP)) ||
1244 (match("NTLM", &token) && (type = SHARED_NT_HASH)) ||
1245 (match("XAUTH", &token) && (type = SHARED_EAP)))
1246 {
1247 if (!load_shared(secrets, line, line_nr, type, ids))
1248 {
1249 break;
1250 }
1251 }
1252 else
1253 {
1254 DBG1(DBG_CFG, "line %d: token must be either "
1255 "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
1256 break;
1257 }
1258 }
1259 chunk_unmap(src);
1260
1261 if (level == 0)
1262 { /* replace secrets in active credential set */
1263 this->creds->replace_secrets(this->creds, secrets, FALSE);
1264 secrets->destroy(secrets);
1265 }
1266 }
1267
1268 /**
1269 * load all certificates from ipsec.d
1270 */
1271 static void load_certs(private_stroke_cred_t *this)
1272 {
1273 DBG1(DBG_CFG, "loading ca certificates from '%s'",
1274 CA_CERTIFICATE_DIR);
1275 load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
1276
1277 DBG1(DBG_CFG, "loading aa certificates from '%s'",
1278 AA_CERTIFICATE_DIR);
1279 load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
1280
1281 DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'",
1282 OCSP_CERTIFICATE_DIR);
1283 load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER);
1284
1285 DBG1(DBG_CFG, "loading attribute certificates from '%s'",
1286 ATTR_CERTIFICATE_DIR);
1287 load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
1288
1289 DBG1(DBG_CFG, "loading crls from '%s'",
1290 CRL_DIR);
1291 load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
1292 }
1293
1294 METHOD(stroke_cred_t, reread, void,
1295 private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
1296 {
1297 if (msg->reread.flags & REREAD_SECRETS)
1298 {
1299 DBG1(DBG_CFG, "rereading secrets");
1300 load_secrets(this, NULL, SECRETS_FILE, 0, prompt);
1301 }
1302 if (msg->reread.flags & REREAD_CACERTS)
1303 {
1304 DBG1(DBG_CFG, "rereading ca certificates from '%s'",
1305 CA_CERTIFICATE_DIR);
1306 load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
1307 }
1308 if (msg->reread.flags & REREAD_OCSPCERTS)
1309 {
1310 DBG1(DBG_CFG, "rereading ocsp signer certificates from '%s'",
1311 OCSP_CERTIFICATE_DIR);
1312 load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
1313 X509_OCSP_SIGNER);
1314 }
1315 if (msg->reread.flags & REREAD_AACERTS)
1316 {
1317 DBG1(DBG_CFG, "rereading aa certificates from '%s'",
1318 AA_CERTIFICATE_DIR);
1319 load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
1320 }
1321 if (msg->reread.flags & REREAD_ACERTS)
1322 {
1323 DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
1324 ATTR_CERTIFICATE_DIR);
1325 load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
1326 }
1327 if (msg->reread.flags & REREAD_CRLS)
1328 {
1329 DBG1(DBG_CFG, "rereading crls from '%s'",
1330 CRL_DIR);
1331 load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
1332 }
1333 }
1334
1335 METHOD(stroke_cred_t, add_shared, void,
1336 private_stroke_cred_t *this, shared_key_t *shared, linked_list_t *owners)
1337 {
1338 this->creds->add_shared_list(this->creds, shared, owners);
1339 }
1340
1341 METHOD(stroke_cred_t, destroy, void,
1342 private_stroke_cred_t *this)
1343 {
1344 lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
1345 this->creds->destroy(this->creds);
1346 free(this);
1347 }
1348
1349 /*
1350 * see header file
1351 */
1352 stroke_cred_t *stroke_cred_create()
1353 {
1354 private_stroke_cred_t *this;
1355
1356 INIT(this,
1357 .public = {
1358 .set = {
1359 .create_private_enumerator = (void*)return_null,
1360 .create_cert_enumerator = (void*)return_null,
1361 .create_shared_enumerator = (void*)return_null,
1362 .create_cdp_enumerator = (void*)return_null,
1363 .cache_cert = (void*)_cache_cert,
1364 },
1365 .reread = _reread,
1366 .load_ca = _load_ca,
1367 .load_peer = _load_peer,
1368 .load_pubkey = _load_pubkey,
1369 .add_shared = _add_shared,
1370 .cachecrl = _cachecrl,
1371 .destroy = _destroy,
1372 },
1373 .creds = mem_cred_create(),
1374 );
1375
1376 lib->credmgr->add_set(lib->credmgr, &this->creds->set);
1377
1378 this->force_ca_cert = lib->settings->get_bool(lib->settings,
1379 "%s.plugins.stroke.ignore_missing_ca_basic_constraint",
1380 FALSE, lib->ns);
1381
1382 load_certs(this);
1383 load_secrets(this, NULL, SECRETS_FILE, 0, NULL);
1384
1385 return &this->public;
1386 }