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>
30 #include "stroke_cred.h"
32 #include <credentials/certificates/x509.h>
33 #include <credentials/certificates/crl.h>
34 #include <credentials/certificates/ac.h>
35 #include <credentials/containers/pkcs12.h>
36 #include <credentials/sets/mem_cred.h>
37 #include <credentials/sets/callback_cred.h>
38 #include <collections/linked_list.h>
39 #include <utils/lexparser.h>
40 #include <threading/rwlock.h>
43 /* configuration directories and files */
44 #define CONFIG_DIR IPSEC_CONFDIR
45 #define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
46 #define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
47 #define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
48 #define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
49 #define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
50 #define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
51 #define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
52 #define CRL_DIR IPSEC_D_DIR "/crls"
53 #define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
55 #define MAX_SECRETS_RECURSION 10
57 typedef struct private_stroke_cred_t private_stroke_cred_t
;
60 * private data of stroke_cred
62 struct private_stroke_cred_t
{
75 * ignore missing CA basic constraint (i.e. treat all certificates in
76 * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
86 /** Length of smartcard specifier parts (module, keyid) */
87 #define SC_PART_LEN 128
90 * Kind of smartcard specifier token
93 SC_FORMAT_SLOT_MODULE_KEYID
,
100 * Parse a smartcard specifier token
102 static smartcard_format_t
parse_smartcard(char *smartcard
, u_int
*slot
,
103 char *module
, char *keyid
)
105 /* The token has one of the following three formats:
106 * - %smartcard<slot>@<module>:<keyid>
107 * - %smartcard<slot>:<keyid>
108 * - %smartcard:<keyid>
110 char buf
[2 * SC_PART_LEN
], *pos
;
112 if (sscanf(smartcard
, "%%smartcard%u@%255s", slot
, buf
) == 2)
114 pos
= strchr(buf
, ':');
117 return SC_FORMAT_INVALID
;
120 snprintf(module
, SC_PART_LEN
, "%s", buf
);
121 snprintf(keyid
, SC_PART_LEN
, "%s", pos
);
122 return SC_FORMAT_SLOT_MODULE_KEYID
;
124 if (sscanf(smartcard
, "%%smartcard%u:%127s", slot
, keyid
) == 2)
126 return SC_FORMAT_SLOT_KEYID
;
128 if (sscanf(smartcard
, "%%smartcard:%127s", keyid
) == 1)
130 return SC_FORMAT_KEYID
;
132 return SC_FORMAT_INVALID
;
136 * Load a credential from a smartcard
138 static certificate_t
*load_from_smartcard(smartcard_format_t format
,
139 u_int slot
, char *module
, char *keyid
,
140 credential_type_t type
, int subtype
)
145 chunk
= chunk_from_hex(chunk_create(keyid
, strlen(keyid
)), NULL
);
148 case SC_FORMAT_SLOT_MODULE_KEYID
:
149 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
150 BUILD_PKCS11_SLOT
, slot
,
151 BUILD_PKCS11_MODULE
, module
,
152 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
154 case SC_FORMAT_SLOT_KEYID
:
155 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
156 BUILD_PKCS11_SLOT
, slot
,
157 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
159 case SC_FORMAT_KEYID
:
160 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
161 BUILD_PKCS11_KEYID
, chunk
, BUILD_END
);
172 METHOD(stroke_cred_t
, load_ca
, certificate_t
*,
173 private_stroke_cred_t
*this, char *filename
)
175 certificate_t
*cert
= NULL
;
178 if (strneq(filename
, "%smartcard", strlen("%smartcard")))
180 smartcard_format_t format
;
181 char module
[SC_PART_LEN
], keyid
[SC_PART_LEN
];
184 format
= parse_smartcard(filename
, &slot
, module
, keyid
);
185 if (format
!= SC_FORMAT_INVALID
)
187 cert
= (certificate_t
*)load_from_smartcard(format
,
188 slot
, module
, keyid
, CRED_CERTIFICATE
, CERT_X509
);
193 if (*filename
== '/')
195 snprintf(path
, sizeof(path
), "%s", filename
);
199 snprintf(path
, sizeof(path
), "%s/%s", CA_CERTIFICATE_DIR
, filename
);
202 if (this->force_ca_cert
)
203 { /* we treat this certificate as a CA certificate even if it has no
204 * CA basic constraint */
205 cert
= lib
->creds
->create(lib
->creds
,
206 CRED_CERTIFICATE
, CERT_X509
,
207 BUILD_FROM_FILE
, path
, BUILD_X509_FLAG
, X509_CA
,
212 cert
= lib
->creds
->create(lib
->creds
,
213 CRED_CERTIFICATE
, CERT_X509
,
214 BUILD_FROM_FILE
, path
,
220 x509_t
*x509
= (x509_t
*)cert
;
222 if (!(x509
->get_flags(x509
) & X509_CA
))
224 DBG1(DBG_CFG
, " ca certificate \"%Y\" misses ca basic constraint, "
225 "discarded", cert
->get_subject(cert
));
229 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
230 cert
->get_subject(cert
), filename
);
231 return this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
236 METHOD(stroke_cred_t
, load_peer
, certificate_t
*,
237 private_stroke_cred_t
*this, char *filename
)
239 certificate_t
*cert
= NULL
;
242 if (strneq(filename
, "%smartcard", strlen("%smartcard")))
244 smartcard_format_t format
;
245 char module
[SC_PART_LEN
], keyid
[SC_PART_LEN
];
248 format
= parse_smartcard(filename
, &slot
, module
, keyid
);
249 if (format
!= SC_FORMAT_INVALID
)
251 cert
= (certificate_t
*)load_from_smartcard(format
,
252 slot
, module
, keyid
, CRED_CERTIFICATE
, CERT_X509
);
257 if (*filename
== '/')
259 snprintf(path
, sizeof(path
), "%s", filename
);
263 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
266 cert
= lib
->creds
->create(lib
->creds
,
267 CRED_CERTIFICATE
, CERT_ANY
,
268 BUILD_FROM_FILE
, path
,
273 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
274 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
275 cert
->get_subject(cert
), filename
);
278 DBG1(DBG_CFG
, " loading certificate from '%s' failed", filename
);
282 METHOD(stroke_cred_t
, load_pubkey
, certificate_t
*,
283 private_stroke_cred_t
*this, char *filename
, identification_t
*identity
)
288 builder_part_t build_part
;
289 key_type_t type
= KEY_ANY
;
291 if (streq(filename
, "%dns"))
295 if (strncaseeq(filename
, "dns:", 4))
296 { /* RFC 3110 format */
297 build_part
= BUILD_BLOB_DNSKEY
;
298 /* not a complete RR, only RSA supported */
302 else if (strncaseeq(filename
, "ssh:", 4))
304 build_part
= BUILD_BLOB_SSHKEY
;
308 { /* try PKCS#1 by default */
309 build_part
= BUILD_BLOB_ASN1_DER
;
311 if (strncaseeq(filename
, "0x", 2) || strncaseeq(filename
, "0s", 2))
313 chunk_t printable_key
, raw_key
;
315 printable_key
= chunk_create(filename
+ 2, strlen(filename
) - 2);
316 raw_key
= strncaseeq(filename
, "0x", 2) ?
317 chunk_from_hex(printable_key
, NULL
) :
318 chunk_from_base64(printable_key
, NULL
);
319 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, type
,
320 build_part
, raw_key
, BUILD_END
);
321 chunk_free(&raw_key
);
324 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
,
326 BUILD_PUBLIC_KEY
, key
,
327 BUILD_SUBJECT
, identity
,
329 type
= key
->get_type(key
);
333 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
334 DBG1(DBG_CFG
, " loaded %N public key for \"%Y\"",
335 key_type_names
, type
, identity
);
339 DBG1(DBG_CFG
, " loading public key for \"%Y\" failed", identity
);
343 if (*filename
== '/')
345 snprintf(path
, sizeof(path
), "%s", filename
);
349 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
352 cert
= lib
->creds
->create(lib
->creds
,
353 CRED_CERTIFICATE
, CERT_TRUSTED_PUBKEY
,
354 BUILD_FROM_FILE
, path
,
355 BUILD_SUBJECT
, identity
,
359 cert
= this->creds
->add_cert_ref(this->creds
, TRUE
, cert
);
360 key
= cert
->get_public_key(cert
);
361 type
= key
->get_type(key
);
363 DBG1(DBG_CFG
, " loaded %N public key for \"%Y\" from '%s'",
364 key_type_names
, type
, identity
, filename
);
367 DBG1(DBG_CFG
, " loading public key for \"%Y\" from '%s' failed",
374 * load trusted certificates from a directory
376 static void load_certdir(private_stroke_cred_t
*this, char *path
,
377 certificate_type_t type
, x509_flag_t flag
)
382 enumerator_t
*enumerator
= enumerator_create_directory(path
);
386 DBG1(DBG_CFG
, " reading directory failed");
390 while (enumerator
->enumerate(enumerator
, NULL
, &file
, &st
))
394 if (!S_ISREG(st
.st_mode
))
396 /* skip special file */
404 if (this->force_ca_cert
)
405 { /* treat this certificate as CA cert even it has no
406 * CA basic constraint */
407 cert
= lib
->creds
->create(lib
->creds
,
408 CRED_CERTIFICATE
, CERT_X509
,
409 BUILD_FROM_FILE
, file
, BUILD_X509_FLAG
,
414 cert
= lib
->creds
->create(lib
->creds
,
415 CRED_CERTIFICATE
, CERT_X509
,
416 BUILD_FROM_FILE
, file
, BUILD_END
);
420 x509_t
*x509
= (x509_t
*)cert
;
422 if (!(x509
->get_flags(x509
) & X509_CA
))
424 DBG1(DBG_CFG
, " ca certificate \"%Y\" lacks "
425 "ca basic constraint, discarded",
426 cert
->get_subject(cert
));
432 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" "
433 "from '%s'", cert
->get_subject(cert
), file
);
438 DBG1(DBG_CFG
, " loading ca certificate from '%s' "
443 { /* for all other flags, we add them to the certificate. */
444 cert
= lib
->creds
->create(lib
->creds
,
445 CRED_CERTIFICATE
, CERT_X509
,
446 BUILD_FROM_FILE
, file
,
447 BUILD_X509_FLAG
, flag
, BUILD_END
);
450 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
451 cert
->get_subject(cert
), file
);
455 DBG1(DBG_CFG
, " loading certificate from '%s' "
461 this->creds
->add_cert(this->creds
, TRUE
, cert
);
465 cert
= lib
->creds
->create(lib
->creds
,
466 CRED_CERTIFICATE
, CERT_X509_CRL
,
467 BUILD_FROM_FILE
, file
,
471 this->creds
->add_crl(this->creds
, (crl_t
*)cert
);
472 DBG1(DBG_CFG
, " loaded crl from '%s'", file
);
476 DBG1(DBG_CFG
, " loading crl from '%s' failed", file
);
480 cert
= lib
->creds
->create(lib
->creds
,
481 CRED_CERTIFICATE
, CERT_X509_AC
,
482 BUILD_FROM_FILE
, file
,
486 this->creds
->add_cert(this->creds
, FALSE
, cert
);
487 DBG1(DBG_CFG
, " loaded attribute certificate from '%s'",
492 DBG1(DBG_CFG
, " loading attribute certificate from '%s' "
500 enumerator
->destroy(enumerator
);
503 METHOD(stroke_cred_t
, cache_cert
, void,
504 private_stroke_cred_t
*this, certificate_t
*cert
)
506 if (cert
->get_type(cert
) == CERT_X509_CRL
&& this->cachecrl
)
508 /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
509 crl_t
*crl
= (crl_t
*)cert
;
512 if (this->creds
->add_crl(this->creds
, crl
))
517 chunk
= crl
->get_authKeyIdentifier(crl
);
518 hex
= chunk_to_hex(chunk
, NULL
, FALSE
);
519 snprintf(buf
, sizeof(buf
), "%s/%s.crl", CRL_DIR
, hex
.ptr
);
522 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &chunk
))
524 chunk_write(chunk
, buf
, "crl", 022, TRUE
);
531 METHOD(stroke_cred_t
, cachecrl
, void,
532 private_stroke_cred_t
*this, bool enabled
)
534 DBG1(DBG_CFG
, "crl caching to %s %s",
535 CRL_DIR
, enabled ?
"enabled" : "disabled");
536 this->cachecrl
= enabled
;
541 * Convert a string of characters into a binary secret
542 * A string between single or double quotes is treated as ASCII characters
543 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
545 static err_t
extract_secret(chunk_t
*secret
, chunk_t
*line
)
548 char delimiter
= ' ';
551 if (!eat_whitespace(line
))
553 return "missing secret";
556 if (*line
->ptr
== '\'' || *line
->ptr
== '"')
559 delimiter
= *line
->ptr
;
560 line
->ptr
++; line
->len
--;
563 if (!extract_token(&raw_secret
, delimiter
, line
))
565 if (delimiter
== ' ')
571 return "missing second delimiter";
577 /* treat as an ASCII string */
578 *secret
= chunk_clone(raw_secret
);
581 /* treat 0x as hex, 0s as base64 */
582 if (raw_secret
.len
> 2)
584 if (strncasecmp("0x", raw_secret
.ptr
, 2) == 0)
586 *secret
= chunk_from_hex(chunk_skip(raw_secret
, 2), NULL
);
589 if (strncasecmp("0s", raw_secret
.ptr
, 2) == 0)
591 *secret
= chunk_from_base64(chunk_skip(raw_secret
, 2), NULL
);
595 *secret
= chunk_clone(raw_secret
);
600 * Data for passphrase callback
603 /** socket we use for prompting */
605 /** private key file */
607 /** number of tries */
609 } passphrase_cb_data_t
;
612 * Callback function to receive Passphrases
614 static shared_key_t
* passphrase_cb(passphrase_cb_data_t
*data
,
615 shared_key_type_t type
,
616 identification_t
*me
, identification_t
*other
,
617 id_match_t
*match_me
, id_match_t
*match_other
)
622 if (type
!= SHARED_ANY
&& type
!= SHARED_PRIVATE_KEY_PASS
)
631 fprintf(data
->prompt
, "PIN invalid, giving up.\n");
634 fprintf(data
->prompt
, "PIN invalid!\n");
637 fprintf(data
->prompt
, "Private key '%s' is encrypted.\n", data
->path
);
638 fprintf(data
->prompt
, "Passphrase:\n");
639 if (fgets(buf
, sizeof(buf
), data
->prompt
))
641 secret
= chunk_create(buf
, strlen(buf
));
643 { /* trim appended \n */
647 *match_me
= ID_MATCH_PERFECT
;
651 *match_other
= ID_MATCH_NONE
;
653 return shared_key_create(SHARED_PRIVATE_KEY_PASS
, chunk_clone(secret
));
660 * Data for PIN callback
663 /** socket we use for prompting */
669 /** number of tries */
674 * Callback function to receive PINs
676 static shared_key_t
* pin_cb(pin_cb_data_t
*data
, shared_key_type_t type
,
677 identification_t
*me
, identification_t
*other
,
678 id_match_t
*match_me
, id_match_t
*match_other
)
683 if (type
!= SHARED_ANY
&& type
!= SHARED_PIN
)
688 if (!me
|| !chunk_equals(me
->get_encoding(me
), data
->keyid
))
695 fprintf(data
->prompt
, "PIN invalid, aborting.\n");
699 fprintf(data
->prompt
, "Login to '%s' required\n", data
->card
);
700 fprintf(data
->prompt
, "PIN:\n");
701 if (fgets(buf
, sizeof(buf
), data
->prompt
))
703 secret
= chunk_create(buf
, strlen(buf
));
705 { /* trim appended \n */
709 *match_me
= ID_MATCH_PERFECT
;
713 *match_other
= ID_MATCH_NONE
;
715 return shared_key_create(SHARED_PIN
, chunk_clone(secret
));
722 * Load a smartcard with a PIN
724 static bool load_pin(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
727 chunk_t sc
= chunk_empty
, secret
= chunk_empty
;
728 char smartcard
[BUF_LEN
], keyid
[SC_PART_LEN
], module
[SC_PART_LEN
];
729 private_key_t
*key
= NULL
;
732 shared_key_t
*shared
;
733 identification_t
*id
;
734 mem_cred_t
*mem
= NULL
;
735 callback_cred_t
*cb
= NULL
;
736 pin_cb_data_t pin_data
;
737 smartcard_format_t format
;
739 err_t ugh
= extract_value(&sc
, &line
);
743 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
748 DBG1(DBG_CFG
, "line %d: expected %%smartcard specifier", line_nr
);
751 snprintf(smartcard
, sizeof(smartcard
), "%.*s", (int)sc
.len
, sc
.ptr
);
752 smartcard
[sizeof(smartcard
) - 1] = '\0';
754 format
= parse_smartcard(smartcard
, &slot
, module
, keyid
);
755 if (format
== SC_FORMAT_INVALID
)
757 DBG1(DBG_CFG
, "line %d: the given %%smartcard specifier is not"
758 " supported or invalid", line_nr
);
762 if (!eat_whitespace(&line
))
764 DBG1(DBG_CFG
, "line %d: expected PIN", line_nr
);
767 ugh
= extract_secret(&secret
, &line
);
770 DBG1(DBG_CFG
, "line %d: malformed PIN: %s", line_nr
, ugh
);
774 chunk
= chunk_from_hex(chunk_create(keyid
, strlen(keyid
)), NULL
);
775 if (secret
.len
== 7 && strneq(secret
.ptr
, "%prompt", 7))
779 { /* no IO channel to prompt, skip */
783 /* use callback credential set to prompt for the pin */
784 pin_data
.prompt
= prompt
;
785 pin_data
.card
= smartcard
;
786 pin_data
.keyid
= chunk
;
788 cb
= callback_cred_create_shared((void*)pin_cb
, &pin_data
);
789 lib
->credmgr
->add_local_set(lib
->credmgr
, &cb
->set
, FALSE
);
793 /* provide our pin in a temporary credential set */
794 shared
= shared_key_create(SHARED_PIN
, secret
);
795 id
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
796 mem
= mem_cred_create();
797 mem
->add_shared(mem
, shared
, id
, NULL
);
798 lib
->credmgr
->add_local_set(lib
->credmgr
, &mem
->set
, FALSE
);
801 /* unlock: smartcard needs the pin and potentially calls public set */
802 key
= (private_key_t
*)load_from_smartcard(format
, slot
, module
, keyid
,
803 CRED_PRIVATE_KEY
, KEY_ANY
);
806 lib
->credmgr
->remove_local_set(lib
->credmgr
, &mem
->set
);
811 lib
->credmgr
->remove_local_set(lib
->credmgr
, &cb
->set
);
818 DBG1(DBG_CFG
, " loaded private key from %.*s", (int)sc
.len
, sc
.ptr
);
819 secrets
->add_key(secrets
, key
);
825 * Load a private key or PKCS#12 container from a file
827 static bool load_from_file(chunk_t line
, int line_nr
, FILE *prompt
,
828 char *path
, int type
, int subtype
,
832 chunk_t secret
= chunk_empty
;
834 err_t ugh
= extract_value(&filename
, &line
);
838 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
841 if (filename
.len
== 0)
843 DBG1(DBG_CFG
, "line %d: empty filename", line_nr
);
846 if (*filename
.ptr
== '/')
848 /* absolute path name */
849 snprintf(path
, PATH_MAX
, "%.*s", (int)filename
.len
, filename
.ptr
);
853 /* relative path name */
854 snprintf(path
, PATH_MAX
, "%s/%.*s", PRIVATE_KEY_DIR
,
855 (int)filename
.len
, filename
.ptr
);
858 /* check for optional passphrase */
859 if (eat_whitespace(&line
))
861 ugh
= extract_secret(&secret
, &line
);
864 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
868 if (secret
.len
== 7 && strneq(secret
.ptr
, "%prompt", 7))
870 callback_cred_t
*cb
= NULL
;
871 passphrase_cb_data_t pp_data
= {
883 /* use callback credential set to prompt for the passphrase */
884 pp_data
.prompt
= prompt
;
887 cb
= callback_cred_create_shared((void*)passphrase_cb
, &pp_data
);
888 lib
->credmgr
->add_local_set(lib
->credmgr
, &cb
->set
, FALSE
);
890 *result
= lib
->creds
->create(lib
->creds
, type
, subtype
,
891 BUILD_FROM_FILE
, path
, BUILD_END
);
893 lib
->credmgr
->remove_local_set(lib
->credmgr
, &cb
->set
);
898 mem_cred_t
*mem
= NULL
;
899 shared_key_t
*shared
;
901 /* provide our pin in a temporary credential set */
902 shared
= shared_key_create(SHARED_PRIVATE_KEY_PASS
, secret
);
903 mem
= mem_cred_create();
904 mem
->add_shared(mem
, shared
, NULL
);
905 lib
->credmgr
->add_local_set(lib
->credmgr
, &mem
->set
, FALSE
);
907 *result
= lib
->creds
->create(lib
->creds
, type
, subtype
,
908 BUILD_FROM_FILE
, path
, BUILD_END
);
910 lib
->credmgr
->remove_local_set(lib
->credmgr
, &mem
->set
);
919 static bool load_private(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
920 FILE *prompt
, key_type_t key_type
)
925 if (!load_from_file(line
, line_nr
, prompt
, path
, CRED_PRIVATE_KEY
,
926 key_type
, (void**)&key
))
932 DBG1(DBG_CFG
, " loaded %N private key from '%s'",
933 key_type_names
, key
->get_type(key
), path
);
934 secrets
->add_key(secrets
, key
);
938 DBG1(DBG_CFG
, " loading private key from '%s' failed", path
);
944 * Load a PKCS#12 container
946 static bool load_pkcs12(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
949 enumerator_t
*enumerator
;
955 if (!load_from_file(line
, line_nr
, prompt
, path
, CRED_CONTAINER
,
956 CONTAINER_PKCS12
, (void**)&pkcs12
))
962 DBG1(DBG_CFG
, " loading credentials from '%s' failed", path
);
965 enumerator
= pkcs12
->create_cert_enumerator(pkcs12
);
966 while (enumerator
->enumerate(enumerator
, &cert
))
968 x509_t
*x509
= (x509_t
*)cert
;
970 if (x509
->get_flags(x509
) & X509_CA
)
972 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
973 cert
->get_subject(cert
), path
);
977 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
978 cert
->get_subject(cert
), path
);
980 secrets
->add_cert(secrets
, TRUE
, cert
->get_ref(cert
));
982 enumerator
->destroy(enumerator
);
983 enumerator
= pkcs12
->create_key_enumerator(pkcs12
);
984 while (enumerator
->enumerate(enumerator
, &key
))
986 DBG1(DBG_CFG
, " loaded %N private key from '%s'",
987 key_type_names
, key
->get_type(key
), path
);
988 secrets
->add_key(secrets
, key
->get_ref(key
));
990 enumerator
->destroy(enumerator
);
991 pkcs12
->container
.destroy(&pkcs12
->container
);
998 static bool load_shared(mem_cred_t
*secrets
, chunk_t line
, int line_nr
,
999 shared_key_type_t type
, chunk_t ids
)
1001 shared_key_t
*shared_key
;
1002 linked_list_t
*owners
;
1003 chunk_t secret
= chunk_empty
;
1006 err_t ugh
= extract_secret(&secret
, &line
);
1009 DBG1(DBG_CFG
, "line %d: malformed secret: %s", line_nr
, ugh
);
1012 shared_key
= shared_key_create(type
, secret
);
1013 DBG1(DBG_CFG
, " loaded %N secret for %s", shared_key_type_names
, type
,
1014 ids
.len
> 0 ?
(char*)ids
.ptr
: "%any");
1015 DBG4(DBG_CFG
, " secret: %#B", &secret
);
1017 owners
= linked_list_create();
1021 identification_t
*peer_id
;
1023 ugh
= extract_value(&id
, &ids
);
1026 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1027 shared_key
->destroy(shared_key
);
1028 owners
->destroy_offset(owners
, offsetof(identification_t
, destroy
));
1036 /* NULL terminate the ID string */
1037 *(id
.ptr
+ id
.len
) = '\0';
1038 peer_id
= identification_create_from_string(id
.ptr
);
1039 if (peer_id
->get_type(peer_id
) == ID_ANY
)
1041 peer_id
->destroy(peer_id
);
1045 owners
->insert_last(owners
, peer_id
);
1050 owners
->insert_last(owners
,
1051 identification_create_from_encoding(ID_ANY
, chunk_empty
));
1053 secrets
->add_shared_list(secrets
, shared_key
, owners
);
1058 * reload ipsec.secrets
1060 static void load_secrets(private_stroke_cred_t
*this, mem_cred_t
*secrets
,
1061 char *file
, int level
, FILE *prompt
)
1063 int line_nr
= 0, fd
;
1068 DBG1(DBG_CFG
, "loading secrets from '%s'", file
);
1069 fd
= open(file
, O_RDONLY
);
1072 DBG1(DBG_CFG
, "opening secrets file '%s' failed: %s", file
,
1076 if (fstat(fd
, &sb
) == -1)
1078 DBG1(DBG_LIB
, "getting file size of '%s' failed: %s", file
,
1083 if (sb
.st_size
== 0)
1084 { /* skip empty files, as mmap() complains */
1088 addr
= mmap(NULL
, sb
.st_size
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
, fd
, 0);
1089 if (addr
== MAP_FAILED
)
1091 DBG1(DBG_LIB
, "mapping '%s' failed: %s", file
, strerror(errno
));
1095 src
= chunk_create(addr
, sb
.st_size
);
1099 secrets
= mem_cred_create();
1102 while (fetchline(&src
, &line
))
1105 shared_key_type_t type
;
1109 if (!eat_whitespace(&line
))
1113 if (line
.len
> strlen("include ") &&
1114 strneq(line
.ptr
, "include ", strlen("include ")))
1116 char **expanded
, *dir
, pattern
[PATH_MAX
];
1119 if (level
> MAX_SECRETS_RECURSION
)
1121 DBG1(DBG_CFG
, "maximum level of %d includes reached, ignored",
1122 MAX_SECRETS_RECURSION
);
1125 /* terminate filename by space */
1126 line
= chunk_skip(line
, strlen("include "));
1127 pos
= memchr(line
.ptr
, ' ', line
.len
);
1130 line
.len
= pos
- line
.ptr
;
1132 if (line
.len
&& line
.ptr
[0] == '/')
1134 if (line
.len
+ 1 > sizeof(pattern
))
1136 DBG1(DBG_CFG
, "include pattern too long, ignored");
1139 snprintf(pattern
, sizeof(pattern
), "%.*s",
1140 (int)line
.len
, line
.ptr
);
1143 { /* use directory of current file if relative */
1147 if (line
.len
+ 1 + strlen(dir
) + 1 > sizeof(pattern
))
1149 DBG1(DBG_CFG
, "include pattern too long, ignored");
1153 snprintf(pattern
, sizeof(pattern
), "%s/%.*s",
1154 dir
, (int)line
.len
, line
.ptr
);
1160 if (glob(pattern
, GLOB_ERR
, NULL
, &buf
) != 0)
1162 DBG1(DBG_CFG
, "expanding file expression '%s' failed",
1167 for (expanded
= buf
.gl_pathv
; *expanded
!= NULL
; expanded
++)
1169 load_secrets(this, secrets
, *expanded
, level
+ 1,
1175 #else /* HAVE_GLOB_H */
1176 /* if glob(3) is not available, try to load pattern directly */
1177 load_secrets(this, secrets
, pattern
, level
+ 1, prompt
);
1178 #endif /* HAVE_GLOB_H */
1182 if (line
.len
> 2 && strneq(": ", line
.ptr
, 2))
1184 /* no ids, skip the ':' */
1189 else if (extract_token_str(&ids
, " : ", &line
))
1191 /* NULL terminate the extracted id string */
1192 *(ids
.ptr
+ ids
.len
) = '\0';
1196 DBG1(DBG_CFG
, "line %d: missing ' : ' separator", line_nr
);
1200 if (!eat_whitespace(&line
) || !extract_token(&token
, ' ', &line
))
1202 DBG1(DBG_CFG
, "line %d: missing token", line_nr
);
1205 if (match("RSA", &token
) || match("ECDSA", &token
))
1207 if (!load_private(secrets
, line
, line_nr
, prompt
,
1208 match("RSA", &token
) ? KEY_RSA
: KEY_ECDSA
))
1213 else if (match("P12", &token
))
1215 if (!load_pkcs12(secrets
, line
, line_nr
, prompt
))
1220 else if (match("PIN", &token
))
1222 if (!load_pin(secrets
, line
, line_nr
, prompt
))
1227 else if ((match("PSK", &token
) && (type
= SHARED_IKE
)) ||
1228 (match("EAP", &token
) && (type
= SHARED_EAP
)) ||
1229 (match("NTLM", &token
) && (type
= SHARED_NT_HASH
)) ||
1230 (match("XAUTH", &token
) && (type
= SHARED_EAP
)))
1232 if (!load_shared(secrets
, line
, line_nr
, type
, ids
))
1239 DBG1(DBG_CFG
, "line %d: token must be either "
1240 "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr
);
1244 munmap(addr
, sb
.st_size
);
1248 { /* replace secrets in active credential set */
1249 this->creds
->replace_secrets(this->creds
, secrets
, FALSE
);
1250 secrets
->destroy(secrets
);
1255 * load all certificates from ipsec.d
1257 static void load_certs(private_stroke_cred_t
*this)
1259 DBG1(DBG_CFG
, "loading ca certificates from '%s'",
1260 CA_CERTIFICATE_DIR
);
1261 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1263 DBG1(DBG_CFG
, "loading aa certificates from '%s'",
1264 AA_CERTIFICATE_DIR
);
1265 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1267 DBG1(DBG_CFG
, "loading ocsp signer certificates from '%s'",
1268 OCSP_CERTIFICATE_DIR
);
1269 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
, X509_OCSP_SIGNER
);
1271 DBG1(DBG_CFG
, "loading attribute certificates from '%s'",
1272 ATTR_CERTIFICATE_DIR
);
1273 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1275 DBG1(DBG_CFG
, "loading crls from '%s'",
1277 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1280 METHOD(stroke_cred_t
, reread
, void,
1281 private_stroke_cred_t
*this, stroke_msg_t
*msg
, FILE *prompt
)
1283 if (msg
->reread
.flags
& REREAD_SECRETS
)
1285 DBG1(DBG_CFG
, "rereading secrets");
1286 load_secrets(this, NULL
, SECRETS_FILE
, 0, prompt
);
1288 if (msg
->reread
.flags
& REREAD_CACERTS
)
1290 DBG1(DBG_CFG
, "rereading ca certificates from '%s'",
1291 CA_CERTIFICATE_DIR
);
1292 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1294 if (msg
->reread
.flags
& REREAD_OCSPCERTS
)
1296 DBG1(DBG_CFG
, "rereading ocsp signer certificates from '%s'",
1297 OCSP_CERTIFICATE_DIR
);
1298 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
,
1301 if (msg
->reread
.flags
& REREAD_AACERTS
)
1303 DBG1(DBG_CFG
, "rereading aa certificates from '%s'",
1304 AA_CERTIFICATE_DIR
);
1305 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1307 if (msg
->reread
.flags
& REREAD_ACERTS
)
1309 DBG1(DBG_CFG
, "rereading attribute certificates from '%s'",
1310 ATTR_CERTIFICATE_DIR
);
1311 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1313 if (msg
->reread
.flags
& REREAD_CRLS
)
1315 DBG1(DBG_CFG
, "rereading crls from '%s'",
1317 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1321 METHOD(stroke_cred_t
, add_shared
, void,
1322 private_stroke_cred_t
*this, shared_key_t
*shared
, linked_list_t
*owners
)
1324 this->creds
->add_shared_list(this->creds
, shared
, owners
);
1327 METHOD(stroke_cred_t
, destroy
, void,
1328 private_stroke_cred_t
*this)
1330 lib
->credmgr
->remove_set(lib
->credmgr
, &this->creds
->set
);
1331 this->creds
->destroy(this->creds
);
1338 stroke_cred_t
*stroke_cred_create()
1340 private_stroke_cred_t
*this;
1345 .create_private_enumerator
= (void*)return_null
,
1346 .create_cert_enumerator
= (void*)return_null
,
1347 .create_shared_enumerator
= (void*)return_null
,
1348 .create_cdp_enumerator
= (void*)return_null
,
1349 .cache_cert
= (void*)_cache_cert
,
1352 .load_ca
= _load_ca
,
1353 .load_peer
= _load_peer
,
1354 .load_pubkey
= _load_pubkey
,
1355 .add_shared
= _add_shared
,
1356 .cachecrl
= _cachecrl
,
1357 .destroy
= _destroy
,
1359 .creds
= mem_cred_create(),
1362 lib
->credmgr
->add_set(lib
->credmgr
, &this->creds
->set
);
1364 this->force_ca_cert
= lib
->settings
->get_bool(lib
->settings
,
1365 "%s.plugins.stroke.ignore_missing_ca_basic_constraint",
1366 FALSE
, charon
->name
);
1369 load_secrets(this, NULL
, SECRETS_FILE
, 0, NULL
);
1371 return &this->public;