2 * Copyright (C) 2008-2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include <sys/types.h>
28 #include "stroke_cred.h"
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>
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"
53 #define MAX_SECRETS_RECURSION 10
55 typedef struct private_stroke_cred_t private_stroke_cred_t
;
58 * private data of stroke_cred
60 struct private_stroke_cred_t
{
68 * secrets file with credential information
73 * credentials: end entity certs, attribute certs, CRLs, etc.
83 * Attribute Authority certificates
88 * ignore missing CA basic constraint (i.e. treat all certificates in
89 * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
99 /** Length of smartcard specifier parts (module, keyid) */
100 #define SC_PART_LEN 128
103 * Kind of smartcard specifier token
106 SC_FORMAT_SLOT_MODULE_KEYID
,
107 SC_FORMAT_SLOT_KEYID
,
110 } smartcard_format_t
;
113 * Parse a smartcard specifier token
115 static smartcard_format_t
parse_smartcard(char *smartcard
, u_int
*slot
,
116 char *module
, char *keyid
)
118 /* The token has one of the following three formats:
119 * - %smartcard<slot>@<module>:<keyid>
120 * - %smartcard<slot>:<keyid>
121 * - %smartcard:<keyid>
123 char buf
[2 * SC_PART_LEN
], *pos
;
125 if (sscanf(smartcard
, "%%smartcard%u@%255s", slot
, buf
) == 2)
127 pos
= strchr(buf
, ':');
130 return SC_FORMAT_INVALID
;
133 snprintf(module
, SC_PART_LEN
, "%s", buf
);
134 snprintf(keyid
, SC_PART_LEN
, "%s", pos
);
135 return SC_FORMAT_SLOT_MODULE_KEYID
;
137 if (sscanf(smartcard
, "%%smartcard%u:%127s", slot
, keyid
) == 2)
139 return SC_FORMAT_SLOT_KEYID
;
141 if (sscanf(smartcard
, "%%smartcard:%127s", keyid
) == 1)
143 return SC_FORMAT_KEYID
;
145 return SC_FORMAT_INVALID
;
149 * Load a credential from a smartcard
151 static certificate_t
*load_from_smartcard(smartcard_format_t format
,
152 u_int slot
, char *module
, char *keyid
,
153 credential_type_t type
, int subtype
)
158 chunk
= chunk_from_hex(chunk_create(keyid
, strlen(keyid
)), NULL
);
161 case SC_FORMAT_SLOT_MODULE_KEYID
:
162 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
163 BUILD_PKCS11_SLOT
, slot
,
164 BUILD_PKCS11_MODULE
, module
,
165 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
167 case SC_FORMAT_SLOT_KEYID
:
168 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
169 BUILD_PKCS11_SLOT
, slot
,
170 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
172 case SC_FORMAT_KEYID
:
173 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
174 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
185 METHOD(stroke_cred_t
, load_ca
, certificate_t
*,
186 private_stroke_cred_t
*this, char *filename
)
188 certificate_t
*cert
= NULL
;
191 if (strpfx(filename
, "%smartcard"))
193 smartcard_format_t format
;
194 char module
[SC_PART_LEN
], keyid
[SC_PART_LEN
];
197 format
= parse_smartcard(filename
, &slot
, module
, keyid
);
198 if (format
!= SC_FORMAT_INVALID
)
200 cert
= (certificate_t
*)load_from_smartcard(format
,
201 slot
, module
, keyid
, CRED_CERTIFICATE
, CERT_X509
);
206 if (*filename
== '/')
208 snprintf(path
, sizeof(path
), "%s", filename
);
212 snprintf(path
, sizeof(path
), "%s/%s", CA_CERTIFICATE_DIR
, filename
);
215 if (this->force_ca_cert
)
216 { /* we treat this certificate as a CA certificate even if it has no
217 * CA basic constraint */
218 cert
= lib
->creds
->create(lib
->creds
,
219 CRED_CERTIFICATE
, CERT_X509
,
220 BUILD_FROM_FILE
, path
, BUILD_X509_FLAG
, X509_CA
,
225 cert
= lib
->creds
->create(lib
->creds
,
226 CRED_CERTIFICATE
, CERT_X509
,
227 BUILD_FROM_FILE
, path
,
233 x509_t
*x509
= (x509_t
*)cert
;
235 if (!(x509
->get_flags(x509
) & X509_CA
))
237 DBG1(DBG_CFG
, " ca certificate \"%Y\" misses ca basic constraint, "
238 "discarded", cert
->get_subject(cert
));
242 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
243 cert
->get_subject(cert
), filename
);
244 return this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
249 METHOD(stroke_cred_t
, load_peer
, certificate_t
*,
250 private_stroke_cred_t
*this, char *filename
)
252 certificate_t
*cert
= NULL
;
255 if (strpfx(filename
, "%smartcard"))
257 smartcard_format_t format
;
258 char module
[SC_PART_LEN
], keyid
[SC_PART_LEN
];
261 format
= parse_smartcard(filename
, &slot
, module
, keyid
);
262 if (format
!= SC_FORMAT_INVALID
)
264 cert
= (certificate_t
*)load_from_smartcard(format
,
265 slot
, module
, keyid
, CRED_CERTIFICATE
, CERT_X509
);
270 if (*filename
== '/')
272 snprintf(path
, sizeof(path
), "%s", filename
);
276 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
279 cert
= lib
->creds
->create(lib
->creds
,
280 CRED_CERTIFICATE
, CERT_ANY
,
281 BUILD_FROM_FILE
, path
,
286 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
287 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
288 cert
->get_subject(cert
), filename
);
291 DBG1(DBG_CFG
, " loading certificate from '%s' failed", filename
);
295 METHOD(stroke_cred_t
, load_pubkey
, certificate_t
*,
296 private_stroke_cred_t
*this, char *filename
, identification_t
*identity
)
301 builder_part_t build_part
;
302 key_type_t type
= KEY_ANY
;
304 if (streq(filename
, "%dns"))
308 if (strncaseeq(filename
, "dns:", 4))
309 { /* RFC 3110 format */
310 build_part
= BUILD_BLOB_DNSKEY
;
311 /* not a complete RR, only RSA supported */
315 else if (strncaseeq(filename
, "ssh:", 4))
317 build_part
= BUILD_BLOB_SSHKEY
;
321 { /* try PKCS#1 by default */
322 build_part
= BUILD_BLOB_ASN1_DER
;
324 if (strncaseeq(filename
, "0x", 2) || strncaseeq(filename
, "0s", 2))
326 chunk_t printable_key
, raw_key
;
328 printable_key
= chunk_create(filename
+ 2, strlen(filename
) - 2);
329 raw_key
= strncaseeq(filename
, "0x", 2) ?
330 chunk_from_hex(printable_key
, NULL
) :
331 chunk_from_base64(printable_key
, NULL
);
332 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, type
,
333 build_part
, raw_key
, BUILD_END
);
334 chunk_free(&raw_key
);
337 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
,
339 BUILD_PUBLIC_KEY
, key
,
340 BUILD_SUBJECT
, identity
,
342 type
= key
->get_type(key
);
346 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
347 DBG1(DBG_CFG
, " loaded %N public key for \"%Y\"",
348 key_type_names
, type
, identity
);
352 DBG1(DBG_CFG
, " loading public key for \"%Y\" failed", identity
);
356 if (*filename
== '/')
358 snprintf(path
, sizeof(path
), "%s", filename
);
362 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
365 cert
= lib
->creds
->create(lib
->creds
,
366 CRED_CERTIFICATE
, CERT_TRUSTED_PUBKEY
,
367 BUILD_FROM_FILE
, path
,
368 BUILD_SUBJECT
, identity
,
372 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
373 key
= cert
->get_public_key(cert
);
374 type
= key
->get_type(key
);
376 DBG1(DBG_CFG
, " loaded %N public key for \"%Y\" from '%s'",
377 key_type_names
, type
, identity
, filename
);
380 DBG1(DBG_CFG
, " loading public key for \"%Y\" from '%s' failed",
387 * Load a CA certificate from disk
389 static void load_x509_ca(private_stroke_cred_t
*this, char *file
)
393 if (this->force_ca_cert
)
394 { /* treat certificate as CA cert even it has no CA basic constraint */
395 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
396 BUILD_FROM_FILE
, file
,
397 BUILD_X509_FLAG
, X509_CA
, BUILD_END
);
401 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
402 BUILD_FROM_FILE
, file
, BUILD_END
);
406 x509_t
*x509
= (x509_t
*)cert
;
408 if (!(x509
->get_flags(x509
) & X509_CA
))
410 DBG1(DBG_CFG
, " ca certificate \"%Y\" lacks ca basic constraint, "
411 "discarded", cert
->get_subject(cert
));
416 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
417 cert
->get_subject(cert
), file
);
418 this->cacerts
->add_cert(this->cacerts
, TRUE
, cert
);
423 DBG1(DBG_CFG
, " loading ca certificate from '%s' failed", file
);
428 * Load AA certificate with flags from disk
430 static void load_x509_aa(private_stroke_cred_t
*this, char *file
)
434 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
435 BUILD_FROM_FILE
, file
,
436 BUILD_X509_FLAG
, X509_AA
, BUILD_END
);
439 DBG1(DBG_CFG
, " loaded AA certificate \"%Y\" from '%s'",
440 cert
->get_subject(cert
), file
);
441 this->aacerts
->add_cert(this->aacerts
, TRUE
, cert
);
445 DBG1(DBG_CFG
, " loading AA certificate from '%s' failed", file
);
450 * Load a certificate with flags from disk
452 static void load_x509(private_stroke_cred_t
*this, char *file
, x509_flag_t flag
)
456 /* for all other flags, we add them to the certificate. */
457 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
458 BUILD_FROM_FILE
, file
,
459 BUILD_X509_FLAG
, flag
, BUILD_END
);
462 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
463 cert
->get_subject(cert
), file
);
464 this->creds
->add_cert(this->creds
, TRUE
, cert
);
468 DBG1(DBG_CFG
, " loading certificate from '%s' failed", file
);
473 * Load a CRL from a file
475 static void load_x509_crl(private_stroke_cred_t
*this, char *file
)
479 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509_CRL
,
480 BUILD_FROM_FILE
, file
, BUILD_END
);
483 this->creds
->add_crl(this->creds
, (crl_t
*)cert
);
484 DBG1(DBG_CFG
, " loaded crl from '%s'", file
);
488 DBG1(DBG_CFG
, " loading crl from '%s' failed", file
);
493 * Load an attribute certificate from a file
495 static void load_x509_ac(private_stroke_cred_t
*this, char *file
)
499 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509_AC
,
500 BUILD_FROM_FILE
, file
, BUILD_END
);
503 DBG1(DBG_CFG
, " loaded attribute certificate from '%s'", file
);
504 this->creds
->add_cert(this->creds
, FALSE
, cert
);
508 DBG1(DBG_CFG
, " loading attribute certificate from '%s' failed", file
);
513 * load trusted certificates from a directory
515 static void load_certdir(private_stroke_cred_t
*this, char *path
,
516 certificate_type_t type
, x509_flag_t flag
)
518 enumerator_t
*enumerator
;
522 enumerator
= enumerator_create_directory(path
);
525 while (enumerator
->enumerate(enumerator
, NULL
, &file
, &st
))
527 if (!S_ISREG(st
.st_mode
))
529 /* skip special file */
537 load_x509_ca(this, file
);
539 else if (flag
& X509_AA
)
541 load_x509_aa(this, file
);
545 load_x509(this, file
, flag
);
549 load_x509_crl(this, file
);
552 load_x509_ac(this, file
);
558 enumerator
->destroy(enumerator
);
562 DBG1(DBG_CFG
, " reading directory failed");
566 METHOD(stroke_cred_t
, cache_cert
, void,
567 private_stroke_cred_t
*this, certificate_t
*cert
)
569 if (cert
->get_type(cert
) == CERT_X509_CRL
&& this->cachecrl
)
571 /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
572 crl_t
*crl
= (crl_t
*)cert
;
575 if (this->creds
->add_crl(this->creds
, crl
))
580 chunk
= crl
->get_authKeyIdentifier(crl
);
581 hex
= chunk_to_hex(chunk
, NULL
, FALSE
);
582 snprintf(buf
, sizeof(buf
), "%s/%s.crl", CRL_DIR
, hex
.ptr
);
585 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &chunk
))
587 if (chunk_write(chunk
, buf
, 022, TRUE
))
589 DBG1(DBG_CFG
, " written crl file '%s' (%d bytes)",
594 DBG1(DBG_CFG
, " writing crl file '%s' failed: %s",
595 buf
, strerror(errno
));
603 METHOD(stroke_cred_t
, cachecrl
, void,
604 private_stroke_cred_t
*this, bool enabled
)
606 DBG1(DBG_CFG
, "crl caching to %s %s",
607 CRL_DIR
, enabled ?
"enabled" : "disabled");
608 this->cachecrl
= enabled
;
613 * Convert a string of characters into a binary secret
614 * A string between single or double quotes is treated as ASCII characters
615 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
617 static err_t
extract_secret(chunk_t
*secret
, chunk_t
*line
)
620 char delimiter
= ' ';
623 if (!eat_whitespace(line
))
625 return "missing secret";
628 if (*line
->ptr
== '\'' || *line
->ptr
== '"')
631 delimiter
= *line
->ptr
;
632 line
->ptr
++; line
->len
--;
635 if (!extract_token(&raw_secret
, delimiter
, line
))
637 if (delimiter
== ' ')
643 return "missing second delimiter";
649 /* treat as an ASCII string */
650 *secret
= chunk_clone(raw_secret
);
653 /* treat 0x as hex, 0s as base64 */
654 if (raw_secret
.len
> 2)
656 if (strncasecmp("0x", raw_secret
.ptr
, 2) == 0)
658 *secret
= chunk_from_hex(chunk_skip(raw_secret
, 2), NULL
);
661 if (strncasecmp("0s", raw_secret
.ptr
, 2) == 0)
663 *secret
= chunk_from_base64(chunk_skip(raw_secret
, 2), NULL
);
667 *secret
= chunk_clone(raw_secret
);
672 * Data for passphrase callback
675 /** cached passphrases */
677 /** socket we use for prompting */
679 /** type of secret to unlock */
681 /** private key file */
683 /** number of tries */
685 } passphrase_cb_data_t
;
688 * Callback function to receive passphrases
690 static shared_key_t
* passphrase_cb(passphrase_cb_data_t
*data
,
691 shared_key_type_t type
, identification_t
*me
,
692 identification_t
*other
, id_match_t
*match_me
,
693 id_match_t
*match_other
)
695 static const int max_tries
= 3;
696 shared_key_t
*shared
;
700 if (type
!= SHARED_ANY
&& type
!= SHARED_PRIVATE_KEY_PASS
)
706 if (data
->try > max_tries
+ 1)
707 { /* another builder might call this after we gave up, fail silently */
710 if (data
->try > max_tries
)
712 fprintf(data
->prompt
, "Passphrase invalid, giving up.\n");
717 fprintf(data
->prompt
, "Passphrase invalid!\n");
719 fprintf(data
->prompt
, "%s '%s' is encrypted.\n",
720 data
->type
== CRED_PRIVATE_KEY ?
"Private key" : "PKCS#12 file",
722 fprintf(data
->prompt
, "Passphrase:\n");
723 if (fgets(buf
, sizeof(buf
), data
->prompt
))
725 secret
= chunk_create(buf
, strlen(buf
));
727 { /* trim appended \n */
731 *match_me
= ID_MATCH_PERFECT
;
735 *match_other
= ID_MATCH_NONE
;
737 shared
= shared_key_create(SHARED_PRIVATE_KEY_PASS
,
738 chunk_clone(secret
));
739 data
->cache
->add_shared(data
->cache
, shared
->get_ref(shared
), NULL
);
747 * Data for PIN callback
750 /** socket we use for prompting */
756 /** number of tries */
761 * Callback function to receive PINs
763 static shared_key_t
* pin_cb(pin_cb_data_t
*data
, shared_key_type_t type
,
764 identification_t
*me
, identification_t
*other
,
765 id_match_t
*match_me
, id_match_t
*match_other
)
770 if (type
!= SHARED_ANY
&& type
!= SHARED_PIN
)
775 if (!me
|| !chunk_equals(me
->get_encoding(me
), data
->keyid
))
783 fprintf(data
->prompt
, "PIN invalid, aborting.\n");
786 fprintf(data
->prompt
, "Login to '%s' required\n", data
->card
);
787 fprintf(data
->prompt
, "PIN:\n");
788 if (fgets(buf
, sizeof(buf
), data
->prompt
))
790 secret
= chunk_create(buf
, strlen(buf
));
792 { /* trim appended \n */
796 *match_me
= ID_MATCH_PERFECT
;
800 *match_other
= ID_MATCH_NONE
;
802 return shared_key_create(SHARED_PIN
, chunk_clone(secret
));
809 * Load a smartcard with a PIN
811 static bool load_pin(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
814 chunk_t sc
= chunk_empty
, secret
= chunk_empty
;
815 char smartcard
[BUF_LEN
], keyid
[SC_PART_LEN
], module
[SC_PART_LEN
];
816 private_key_t
*key
= NULL
;
819 shared_key_t
*shared
;
820 identification_t
*id
;
821 mem_cred_t
*mem
= NULL
;
822 callback_cred_t
*cb
= NULL
;
823 pin_cb_data_t pin_data
;
824 smartcard_format_t format
;
826 err_t ugh
= extract_value(&sc
, &line
);
830 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
835 DBG1(DBG_CFG
, "line %d: expected %%smartcard specifier", line_nr
);
838 snprintf(smartcard
, sizeof(smartcard
), "%.*s", (int)sc
.len
, sc
.ptr
);
839 smartcard
[sizeof(smartcard
) - 1] = '\0';
841 format
= parse_smartcard(smartcard
, &slot
, module
, keyid
);
842 if (format
== SC_FORMAT_INVALID
)
844 DBG1(DBG_CFG
, "line %d: the given %%smartcard specifier is not"
845 " supported or invalid", line_nr
);
849 if (!eat_whitespace(&line
))
851 DBG1(DBG_CFG
, "line %d: expected PIN", line_nr
);
854 ugh
= extract_secret(&secret
, &line
);
857 DBG1(DBG_CFG
, "line %d: malformed PIN: %s", line_nr
, ugh
);
861 chunk
= chunk_from_hex(chunk_create(keyid
, strlen(keyid
)), NULL
);
862 if (secret
.len
== 7 && strpfx(secret
.ptr
, "%prompt"))
866 { /* no IO channel to prompt, skip */
870 /* use callback credential set to prompt for the pin */
871 pin_data
.prompt
= prompt
;
872 pin_data
.card
= smartcard
;
873 pin_data
.keyid
= chunk
;
875 cb
= callback_cred_create_shared((void*)pin_cb
, &pin_data
);
876 lib
->credmgr
->add_local_set(lib
->credmgr
, &cb
->set
, FALSE
);
880 /* provide our pin in a temporary credential set */
881 shared
= shared_key_create(SHARED_PIN
, secret
);
882 id
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
883 mem
= mem_cred_create();
884 mem
->add_shared(mem
, shared
, id
, NULL
);
885 lib
->credmgr
->add_local_set(lib
->credmgr
, &mem
->set
, FALSE
);
888 /* unlock: smartcard needs the pin and potentially calls public set */
889 key
= (private_key_t
*)load_from_smartcard(format
, slot
, module
, keyid
,
890 CRED_PRIVATE_KEY
, KEY_ANY
);
893 lib
->credmgr
->remove_local_set(lib
->credmgr
, &mem
->set
);
898 lib
->credmgr
->remove_local_set(lib
->credmgr
, &cb
->set
);
905 DBG1(DBG_CFG
, " loaded private key from %.*s", (int)sc
.len
, sc
.ptr
);
906 secrets
->add_key(secrets
, key
);
912 * Load a private key or PKCS#12 container from a file
914 static bool load_from_file(chunk_t line
, int line_nr
, FILE *prompt
,
915 char *path
, int type
, int subtype
,
919 chunk_t secret
= chunk_empty
;
921 err_t ugh
= extract_value(&filename
, &line
);
925 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
928 if (filename
.len
== 0)
930 DBG1(DBG_CFG
, "line %d: empty filename", line_nr
);
933 if (*filename
.ptr
== '/')
935 /* absolute path name */
936 snprintf(path
, PATH_MAX
, "%.*s", (int)filename
.len
, filename
.ptr
);
940 /* relative path name */
941 snprintf(path
, PATH_MAX
, "%s/%.*s", PRIVATE_KEY_DIR
,
942 (int)filename
.len
, filename
.ptr
);
945 /* check for optional passphrase */
946 if (eat_whitespace(&line
))
948 ugh
= extract_secret(&secret
, &line
);
951 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
955 if (secret
.len
== 7 && strpfx(secret
.ptr
, "%prompt"))
958 passphrase_cb_data_t pp_data
= {
971 /* add cache first so if valid passphrases are needed multiple times
972 * the callback is not called anymore */
973 pp_data
.cache
= mem_cred_create();
974 lib
->credmgr
->add_local_set(lib
->credmgr
, &pp_data
.cache
->set
, FALSE
);
975 /* use callback credential set to prompt for the passphrase */
976 cb
= callback_cred_create_shared((void*)passphrase_cb
, &pp_data
);
977 lib
->credmgr
->add_local_set(lib
->credmgr
, &cb
->set
, FALSE
);
979 *result
= lib
->creds
->create(lib
->creds
, type
, subtype
,
980 BUILD_FROM_FILE
, path
, BUILD_END
);
982 lib
->credmgr
->remove_local_set(lib
->credmgr
, &cb
->set
);
984 lib
->credmgr
->remove_local_set(lib
->credmgr
, &pp_data
.cache
->set
);
985 pp_data
.cache
->destroy(pp_data
.cache
);
989 mem_cred_t
*mem
= NULL
;
990 shared_key_t
*shared
;
992 /* provide our pin in a temporary credential set */
993 shared
= shared_key_create(SHARED_PRIVATE_KEY_PASS
, secret
);
994 mem
= mem_cred_create();
995 mem
->add_shared(mem
, shared
, NULL
);
996 if (eat_whitespace(&line
))
997 { /* if there is a second passphrase add that too, could be needed for
998 * PKCS#12 files using different passwords for MAC and encryption */
999 ugh
= extract_secret(&secret
, &line
);
1002 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
1006 shared
= shared_key_create(SHARED_PRIVATE_KEY_PASS
, secret
);
1007 mem
->add_shared(mem
, shared
, NULL
);
1009 lib
->credmgr
->add_local_set(lib
->credmgr
, &mem
->set
, FALSE
);
1011 *result
= lib
->creds
->create(lib
->creds
, type
, subtype
,
1012 BUILD_FROM_FILE
, path
, BUILD_END
);
1014 lib
->credmgr
->remove_local_set(lib
->credmgr
, &mem
->set
);
1021 * Load a private key
1023 static bool load_private(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
1024 FILE *prompt
, key_type_t key_type
)
1026 char path
[PATH_MAX
];
1029 if (!load_from_file(line
, line_nr
, prompt
, path
, CRED_PRIVATE_KEY
,
1030 key_type
, (void**)&key
))
1036 DBG1(DBG_CFG
, " loaded %N private key from '%s'",
1037 key_type_names
, key
->get_type(key
), path
);
1038 secrets
->add_key(secrets
, key
);
1042 DBG1(DBG_CFG
, " loading private key from '%s' failed", path
);
1048 * Load a PKCS#12 container
1050 static bool load_pkcs12(private_stroke_cred_t
*this, mem_cred_t
*secrets
,
1051 chunk_t line
, int line_nr
, FILE *prompt
)
1053 enumerator_t
*enumerator
;
1054 char path
[PATH_MAX
];
1055 certificate_t
*cert
;
1059 if (!load_from_file(line
, line_nr
, prompt
, path
, CRED_CONTAINER
,
1060 CONTAINER_PKCS12
, (void**)&pkcs12
))
1066 DBG1(DBG_CFG
, " loading credentials from '%s' failed", path
);
1069 enumerator
= pkcs12
->create_cert_enumerator(pkcs12
);
1070 while (enumerator
->enumerate(enumerator
, &cert
))
1072 x509_t
*x509
= (x509_t
*)cert
;
1074 if (x509
->get_flags(x509
) & X509_CA
)
1076 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
1077 cert
->get_subject(cert
), path
);
1081 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
1082 cert
->get_subject(cert
), path
);
1084 this->creds
->add_cert(this->creds
, TRUE
, cert
->get_ref(cert
));
1086 enumerator
->destroy(enumerator
);
1087 enumerator
= pkcs12
->create_key_enumerator(pkcs12
);
1088 while (enumerator
->enumerate(enumerator
, &key
))
1090 DBG1(DBG_CFG
, " loaded %N private key from '%s'",
1091 key_type_names
, key
->get_type(key
), path
);
1092 secrets
->add_key(secrets
, key
->get_ref(key
));
1094 enumerator
->destroy(enumerator
);
1095 pkcs12
->container
.destroy(&pkcs12
->container
);
1102 static bool load_shared(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
1103 shared_key_type_t type
, chunk_t ids
)
1105 shared_key_t
*shared_key
;
1106 linked_list_t
*owners
;
1107 chunk_t secret
= chunk_empty
;
1110 err_t ugh
= extract_secret(&secret
, &line
);
1113 DBG1(DBG_CFG
, "line %d: malformed secret: %s", line_nr
, ugh
);
1116 shared_key
= shared_key_create(type
, secret
);
1117 DBG1(DBG_CFG
, " loaded %N secret for %s", shared_key_type_names
, type
,
1118 ids
.len
> 0 ?
(char*)ids
.ptr
: "%any");
1119 DBG4(DBG_CFG
, " secret: %#B", &secret
);
1121 owners
= linked_list_create();
1125 identification_t
*peer_id
;
1127 ugh
= extract_value(&id
, &ids
);
1130 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1131 shared_key
->destroy(shared_key
);
1132 owners
->destroy_offset(owners
, offsetof(identification_t
, destroy
));
1140 /* NULL terminate the ID string */
1141 *(id
.ptr
+ id
.len
) = '\0';
1142 peer_id
= identification_create_from_string(id
.ptr
);
1143 if (peer_id
->get_type(peer_id
) == ID_ANY
)
1145 peer_id
->destroy(peer_id
);
1149 owners
->insert_last(owners
, peer_id
);
1154 owners
->insert_last(owners
,
1155 identification_create_from_encoding(ID_ANY
, chunk_empty
));
1157 secrets
->add_shared_list(secrets
, shared_key
, owners
);
1162 * reload ipsec.secrets
1164 static void load_secrets(private_stroke_cred_t
*this, mem_cred_t
*secrets
,
1165 char *file
, int level
, FILE *prompt
)
1170 DBG1(DBG_CFG
, "loading secrets from '%s'", file
);
1171 src
= chunk_map(file
, FALSE
);
1174 DBG1(DBG_CFG
, "opening secrets file '%s' failed: %s", file
,
1181 secrets
= mem_cred_create();
1184 while (fetchline(src
, &line
))
1187 key_type_t key_type
;
1188 shared_key_type_t type
;
1192 if (!eat_whitespace(&line
))
1196 if (line
.len
> strlen("include ") && strpfx(line
.ptr
, "include "))
1198 char **expanded
, *dir
, pattern
[PATH_MAX
];
1201 if (level
> MAX_SECRETS_RECURSION
)
1203 DBG1(DBG_CFG
, "maximum level of %d includes reached, ignored",
1204 MAX_SECRETS_RECURSION
);
1207 /* terminate filename by space */
1208 line
= chunk_skip(line
, strlen("include "));
1209 pos
= memchr(line
.ptr
, ' ', line
.len
);
1212 line
.len
= pos
- line
.ptr
;
1214 if (line
.len
&& line
.ptr
[0] == '/')
1216 if (line
.len
+ 1 > sizeof(pattern
))
1218 DBG1(DBG_CFG
, "include pattern too long, ignored");
1221 snprintf(pattern
, sizeof(pattern
), "%.*s",
1222 (int)line
.len
, line
.ptr
);
1225 { /* use directory of current file if relative */
1226 dir
= path_dirname(file
);
1228 if (line
.len
+ 1 + strlen(dir
) + 1 > sizeof(pattern
))
1230 DBG1(DBG_CFG
, "include pattern too long, ignored");
1234 snprintf(pattern
, sizeof(pattern
), "%s/%.*s",
1235 dir
, (int)line
.len
, line
.ptr
);
1241 if (glob(pattern
, GLOB_ERR
, NULL
, &buf
) != 0)
1243 DBG1(DBG_CFG
, "expanding file expression '%s' failed",
1248 for (expanded
= buf
.gl_pathv
; *expanded
!= NULL
; expanded
++)
1250 load_secrets(this, secrets
, *expanded
, level
+ 1,
1256 #else /* HAVE_GLOB_H */
1257 /* if glob(3) is not available, try to load pattern directly */
1258 load_secrets(this, secrets
, pattern
, level
+ 1, prompt
);
1259 #endif /* HAVE_GLOB_H */
1263 if (line
.len
> 2 && strpfx(line
.ptr
, ": "))
1265 /* no ids, skip the ':' */
1270 else if (extract_token_str(&ids
, " : ", &line
))
1272 /* NULL terminate the extracted id string */
1273 *(ids
.ptr
+ ids
.len
) = '\0';
1277 DBG1(DBG_CFG
, "line %d: missing ' : ' separator", line_nr
);
1281 if (!eat_whitespace(&line
) || !extract_token(&token
, ' ', &line
))
1283 DBG1(DBG_CFG
, "line %d: missing token", line_nr
);
1286 if (match("RSA", &token
) || match("ECDSA", &token
) ||
1287 match("BLISS", &token
))
1289 if (match("RSA", &token
))
1293 else if (match("ECDSA", &token
))
1295 key_type
= KEY_ECDSA
;
1299 key_type
= KEY_BLISS
;
1301 if (!load_private(secrets
, line
, line_nr
, prompt
, key_type
))
1306 else if (match("P12", &token
))
1308 if (!load_pkcs12(this, secrets
, line
, line_nr
, prompt
))
1313 else if (match("PIN", &token
))
1315 if (!load_pin(secrets
, line
, line_nr
, prompt
))
1320 else if ((match("PSK", &token
) && (type
= SHARED_IKE
)) ||
1321 (match("EAP", &token
) && (type
= SHARED_EAP
)) ||
1322 (match("NTLM", &token
) && (type
= SHARED_NT_HASH
)) ||
1323 (match("XAUTH", &token
) && (type
= SHARED_EAP
)))
1325 if (!load_shared(secrets
, line
, line_nr
, type
, ids
))
1332 DBG1(DBG_CFG
, "line %d: token must be either RSA, ECDSA, BLISS, "
1333 "P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr
);
1340 { /* replace secrets in active credential set */
1341 this->creds
->replace_secrets(this->creds
, secrets
, FALSE
);
1342 secrets
->destroy(secrets
);
1347 * load all certificates from ipsec.d
1349 static void load_certs(private_stroke_cred_t
*this)
1351 DBG1(DBG_CFG
, "loading ca certificates from '%s'",
1352 CA_CERTIFICATE_DIR
);
1353 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1355 DBG1(DBG_CFG
, "loading aa certificates from '%s'",
1356 AA_CERTIFICATE_DIR
);
1357 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1359 DBG1(DBG_CFG
, "loading ocsp signer certificates from '%s'",
1360 OCSP_CERTIFICATE_DIR
);
1361 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
, X509_OCSP_SIGNER
);
1363 DBG1(DBG_CFG
, "loading attribute certificates from '%s'",
1364 ATTR_CERTIFICATE_DIR
);
1365 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1367 DBG1(DBG_CFG
, "loading crls from '%s'",
1369 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1372 METHOD(stroke_cred_t
, reread
, void,
1373 private_stroke_cred_t
*this, stroke_msg_t
*msg
, FILE *prompt
)
1375 if (msg
->reread
.flags
& REREAD_SECRETS
)
1377 DBG1(DBG_CFG
, "rereading secrets");
1378 load_secrets(this, NULL
, this->secrets_file
, 0, prompt
);
1380 if (msg
->reread
.flags
& REREAD_CACERTS
)
1382 DBG1(DBG_CFG
, "rereading ca certificates from '%s'",
1383 CA_CERTIFICATE_DIR
);
1384 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1386 if (msg
->reread
.flags
& REREAD_OCSPCERTS
)
1388 DBG1(DBG_CFG
, "rereading ocsp signer certificates from '%s'",
1389 OCSP_CERTIFICATE_DIR
);
1390 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
,
1393 if (msg
->reread
.flags
& REREAD_AACERTS
)
1395 DBG1(DBG_CFG
, "rereading aa certificates from '%s'",
1396 AA_CERTIFICATE_DIR
);
1397 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1399 if (msg
->reread
.flags
& REREAD_ACERTS
)
1401 DBG1(DBG_CFG
, "rereading attribute certificates from '%s'",
1402 ATTR_CERTIFICATE_DIR
);
1403 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1405 if (msg
->reread
.flags
& REREAD_CRLS
)
1407 DBG1(DBG_CFG
, "rereading crls from '%s'",
1409 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1413 METHOD(stroke_cred_t
, add_shared
, void,
1414 private_stroke_cred_t
*this, shared_key_t
*shared
, linked_list_t
*owners
)
1416 this->creds
->add_shared_list(this->creds
, shared
, owners
);
1419 METHOD(stroke_cred_t
, destroy
, void,
1420 private_stroke_cred_t
*this)
1422 lib
->credmgr
->remove_set(lib
->credmgr
, &this->aacerts
->set
);
1423 lib
->credmgr
->remove_set(lib
->credmgr
, &this->cacerts
->set
);
1424 lib
->credmgr
->remove_set(lib
->credmgr
, &this->creds
->set
);
1425 this->aacerts
->destroy(this->aacerts
);
1426 this->cacerts
->destroy(this->cacerts
);
1427 this->creds
->destroy(this->creds
);
1434 stroke_cred_t
*stroke_cred_create()
1436 private_stroke_cred_t
*this;
1441 .create_private_enumerator
= (void*)return_null
,
1442 .create_cert_enumerator
= (void*)return_null
,
1443 .create_shared_enumerator
= (void*)return_null
,
1444 .create_cdp_enumerator
= (void*)return_null
,
1445 .cache_cert
= (void*)_cache_cert
,
1448 .load_ca
= _load_ca
,
1449 .load_peer
= _load_peer
,
1450 .load_pubkey
= _load_pubkey
,
1451 .add_shared
= _add_shared
,
1452 .cachecrl
= _cachecrl
,
1453 .destroy
= _destroy
,
1455 .secrets_file
= lib
->settings
->get_str(lib
->settings
,
1456 "%s.plugins.stroke.secrets_file", SECRETS_FILE
,
1458 .creds
= mem_cred_create(),
1459 .cacerts
= mem_cred_create(),
1460 .aacerts
= mem_cred_create(),
1463 lib
->credmgr
->add_set(lib
->credmgr
, &this->creds
->set
);
1464 lib
->credmgr
->add_set(lib
->credmgr
, &this->cacerts
->set
);
1465 lib
->credmgr
->add_set(lib
->credmgr
, &this->aacerts
->set
);
1467 this->force_ca_cert
= lib
->settings
->get_bool(lib
->settings
,
1468 "%s.plugins.stroke.ignore_missing_ca_basic_constraint",
1472 load_secrets(this, NULL
, this->secrets_file
, 0, NULL
);
1474 return &this->public;