2 * Copyright (C) 2008 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
22 #include "stroke_cred.h"
23 #include "stroke_shared_key.h"
25 #include <credentials/certificates/x509.h>
26 #include <credentials/certificates/crl.h>
27 #include <credentials/certificates/ac.h>
28 #include <utils/linked_list.h>
29 #include <utils/lexparser.h>
30 #include <utils/mutex.h>
33 /* configuration directories and files */
34 #define CONFIG_DIR IPSEC_CONFDIR
35 #define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
36 #define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
37 #define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
38 #define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
39 #define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
40 #define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
41 #define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
42 #define CRL_DIR IPSEC_D_DIR "/crls"
43 #define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
45 #define MAX_SECRETS_RECURSION 10
47 typedef struct private_stroke_cred_t private_stroke_cred_t
;
50 * private data of stroke_cred
52 struct private_stroke_cred_t
{
60 * list of trusted peer/signer/CA certificates (certificate_t)
65 * list of shared secrets (private_shared_key_t)
67 linked_list_t
*shared
;
70 * list of private keys (private_key_t)
72 linked_list_t
*private;
75 * read-write lock to lists
86 * data to pass to various filters
89 private_stroke_cred_t
*this;
94 * destroy id enumerator data and unlock list
96 static void id_data_destroy(id_data_t
*data
)
98 data
->this->lock
->unlock(data
->this->lock
);
103 * filter function for private key enumerator
105 static bool private_filter(id_data_t
*data
,
106 private_key_t
**in
, private_key_t
**out
)
112 if (data
->id
== NULL
)
117 if (key
->get_fingerprint(key
, KEY_ID_PUBKEY_SHA1
, &keyid
) &&
118 chunk_equals(keyid
, data
->id
->get_encoding(data
->id
)))
127 * Implements credential_set_t.create_private_enumerator
129 static enumerator_t
* create_private_enumerator(private_stroke_cred_t
*this,
130 key_type_t type
, identification_t
*id
)
134 data
= malloc_thing(id_data_t
);
138 this->lock
->read_lock(this->lock
);
139 return enumerator_create_filter(this->private->create_enumerator(this->private),
140 (void*)private_filter
, data
,
141 (void*)id_data_destroy
);
145 * filter function for certs enumerator
147 static bool certs_filter(id_data_t
*data
, certificate_t
**in
, certificate_t
**out
)
149 public_key_t
*public;
150 certificate_t
*cert
= *in
;
153 if (cert
->get_type(cert
) == CERT_X509_CRL
||
154 cert
->get_type(cert
) == CERT_X509_AC
)
158 if (data
->id
== NULL
|| cert
->has_subject(cert
, data
->id
))
164 public = cert
->get_public_key(cert
);
167 if (public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1
, &keyid
) &&
168 chunk_equals(keyid
, data
->id
->get_encoding(data
->id
)))
170 public->destroy(public);
174 public->destroy(public);
180 * filter function for crl enumerator
182 static bool crl_filter(id_data_t
*data
, certificate_t
**in
, certificate_t
**out
)
184 certificate_t
*cert
= *in
;
186 if (cert
->get_type(cert
) != CERT_X509_CRL
)
191 if (data
->id
== NULL
|| cert
->has_issuer(cert
, data
->id
))
200 * filter function for attribute certificate enumerator
202 static bool ac_filter(id_data_t
*data
, certificate_t
**in
, certificate_t
**out
)
204 certificate_t
*cert
= *in
;
206 if (cert
->get_type(cert
) != CERT_X509_AC
)
211 if (data
->id
== NULL
|| cert
->has_subject(cert
, data
->id
))
220 * Implements credential_set_t.create_cert_enumerator
222 static enumerator_t
* create_cert_enumerator(private_stroke_cred_t
*this,
223 certificate_type_t cert
, key_type_t key
,
224 identification_t
*id
, bool trusted
)
228 if (cert
== CERT_X509_CRL
|| cert
== CERT_X509_AC
)
234 data
= malloc_thing(id_data_t
);
238 this->lock
->read_lock(this->lock
);
239 return enumerator_create_filter(this->certs
->create_enumerator(this->certs
),
240 (cert
== CERT_X509_CRL
)? (void*)crl_filter
: (void*)ac_filter
,
241 data
, (void*)id_data_destroy
);
243 if (cert
!= CERT_X509
&& cert
!= CERT_ANY
)
244 { /* we only have X509 certificates. TODO: ACs? */
247 data
= malloc_thing(id_data_t
);
251 this->lock
->read_lock(this->lock
);
252 return enumerator_create_filter(this->certs
->create_enumerator(this->certs
),
253 (void*)certs_filter
, data
,
254 (void*)id_data_destroy
);
258 private_stroke_cred_t
*this;
259 identification_t
*me
;
260 identification_t
*other
;
261 shared_key_type_t type
;
265 * free shared key enumerator data and unlock list
267 static void shared_data_destroy(shared_data_t
*data
)
269 data
->this->lock
->unlock(data
->this->lock
);
274 * filter function for certs enumerator
276 static bool shared_filter(shared_data_t
*data
,
277 stroke_shared_key_t
**in
, shared_key_t
**out
,
278 void **unused1
, id_match_t
*me
,
279 void **unused2
, id_match_t
*other
)
281 id_match_t my_match
, other_match
;
282 stroke_shared_key_t
*stroke
= *in
;
283 shared_key_t
*shared
= &stroke
->shared
;
285 if (data
->type
!= SHARED_ANY
&& shared
->get_type(shared
) != data
->type
)
290 my_match
= stroke
->has_owner(stroke
, data
->me
);
291 other_match
= stroke
->has_owner(stroke
, data
->other
);
292 if (!my_match
&& !other_match
)
303 *other
= other_match
;
309 * Implements credential_set_t.create_shared_enumerator
311 static enumerator_t
* create_shared_enumerator(private_stroke_cred_t
*this,
312 shared_key_type_t type
, identification_t
*me
,
313 identification_t
*other
)
315 shared_data_t
*data
= malloc_thing(shared_data_t
);
321 this->lock
->read_lock(this->lock
);
322 return enumerator_create_filter(this->shared
->create_enumerator(this->shared
),
323 (void*)shared_filter
, data
,
324 (void*)shared_data_destroy
);
328 * Add a certificate to chain
330 static certificate_t
* add_cert(private_stroke_cred_t
*this, certificate_t
*cert
)
332 certificate_t
*current
;
333 enumerator_t
*enumerator
;
336 this->lock
->read_lock(this->lock
);
337 enumerator
= this->certs
->create_enumerator(this->certs
);
338 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
340 if (current
->equals(current
, cert
))
342 /* cert already in queue */
349 enumerator
->destroy(enumerator
);
353 this->certs
->insert_last(this->certs
, cert
);
355 this->lock
->unlock(this->lock
);
360 * Implementation of stroke_cred_t.load_ca.
362 static certificate_t
* load_ca(private_stroke_cred_t
*this, char *filename
)
367 if (*filename
== '/')
369 snprintf(path
, sizeof(path
), "%s", filename
);
373 snprintf(path
, sizeof(path
), "%s/%s", CA_CERTIFICATE_DIR
, filename
);
376 cert
= lib
->creds
->create(lib
->creds
,
377 CRED_CERTIFICATE
, CERT_X509
,
378 BUILD_FROM_FILE
, path
,
382 x509_t
*x509
= (x509_t
*)cert
;
384 if (!(x509
->get_flags(x509
) & X509_CA
))
386 DBG1(DBG_CFG
, " ca certificate '%Y' misses ca basic constraint, "
387 "discarded", cert
->get_subject(cert
));
391 return (certificate_t
*)add_cert(this, cert
);
397 * Add X.509 CRL to chain
399 static bool add_crl(private_stroke_cred_t
*this, crl_t
* crl
)
401 certificate_t
*current
, *cert
= &crl
->certificate
;
402 enumerator_t
*enumerator
;
403 bool new = TRUE
, found
= FALSE
;
405 this->lock
->write_lock(this->lock
);
406 enumerator
= this->certs
->create_enumerator(this->certs
);
407 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
409 if (current
->get_type(current
) == CERT_X509_CRL
)
411 crl_t
*crl_c
= (crl_t
*)current
;
412 chunk_t authkey
= crl
->get_authKeyIdentifier(crl
);
413 chunk_t authkey_c
= crl_c
->get_authKeyIdentifier(crl_c
);
415 /* if compare authorityKeyIdentifiers if available */
416 if (authkey
.ptr
&& authkey_c
.ptr
&& chunk_equals(authkey
, authkey_c
))
422 identification_t
*issuer
= cert
->get_issuer(cert
);
423 identification_t
*issuer_c
= current
->get_issuer(current
);
425 /* otherwise compare issuer distinguished names */
426 if (issuer
->equals(issuer
, issuer_c
))
433 new = cert
->is_newer(cert
, current
);
436 this->certs
->remove_at(this->certs
, enumerator
);
446 enumerator
->destroy(enumerator
);
450 this->certs
->insert_last(this->certs
, cert
);
452 this->lock
->unlock(this->lock
);
457 * Add X.509 attribute certificate to chain
459 static bool add_ac(private_stroke_cred_t
*this, ac_t
* ac
)
461 certificate_t
*cert
= &ac
->certificate
;
463 this->lock
->write_lock(this->lock
);
464 this->certs
->insert_last(this->certs
, cert
);
465 this->lock
->unlock(this->lock
);
470 * Implementation of stroke_cred_t.load_peer.
472 static certificate_t
* load_peer(private_stroke_cred_t
*this, char *filename
)
477 if (*filename
== '/')
479 snprintf(path
, sizeof(path
), "%s", filename
);
483 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
486 cert
= lib
->creds
->create(lib
->creds
,
487 CRED_CERTIFICATE
, CERT_X509
,
488 BUILD_FROM_FILE
, path
,
493 cert
= add_cert(this, cert
);
494 DBG1(DBG_CFG
, " loaded certificate '%Y' from "
495 "file '%s'", cert
->get_subject(cert
), filename
);
496 return cert
->get_ref(cert
);
498 DBG1(DBG_CFG
, " loading certificate from file "
499 "'%s' failed", filename
);
504 * load trusted certificates from a directory
506 static void load_certdir(private_stroke_cred_t
*this, char *path
,
507 certificate_type_t type
, x509_flag_t flag
)
512 enumerator_t
*enumerator
= enumerator_create_directory(path
);
516 DBG1(DBG_CFG
, " reading directory failed");
520 while (enumerator
->enumerate(enumerator
, NULL
, &file
, &st
))
524 if (!S_ISREG(st
.st_mode
))
526 /* skip special file */
533 { /* for CA certificates, we strictly require CA
534 * basicconstraints to be set */
535 cert
= lib
->creds
->create(lib
->creds
,
536 CRED_CERTIFICATE
, CERT_X509
,
537 BUILD_FROM_FILE
, file
, BUILD_END
);
540 x509_t
*x509
= (x509_t
*)cert
;
542 if (!(x509
->get_flags(x509
) & X509_CA
))
544 DBG1(DBG_CFG
, " ca certificate '%Y' misses "
545 "ca basic constraint, discarded",
546 cert
->get_subject(cert
));
552 DBG1(DBG_CFG
, " loaded CA certificate '%Y' from "
553 "file '%s'", cert
->get_subject(cert
), file
);
558 DBG1(DBG_CFG
, " loading CA certificate from file "
559 "'%s' failed", file
);
563 { /* for all other flags, we add them to the certificate. */
564 cert
= lib
->creds
->create(lib
->creds
,
565 CRED_CERTIFICATE
, CERT_X509
,
566 BUILD_FROM_FILE
, file
,
567 BUILD_X509_FLAG
, flag
, BUILD_END
);
570 DBG1(DBG_CFG
, " loaded certificate '%Y' from "
571 "file '%s'", cert
->get_subject(cert
), file
);
575 DBG1(DBG_CFG
, " loading certificate from file "
576 "'%s' failed", file
);
581 add_cert(this, cert
);
585 cert
= lib
->creds
->create(lib
->creds
,
586 CRED_CERTIFICATE
, CERT_X509_CRL
,
587 BUILD_FROM_FILE
, file
,
591 add_crl(this, (crl_t
*)cert
);
592 DBG1(DBG_CFG
, " loaded crl from file '%s'", file
);
596 DBG1(DBG_CFG
, " loading crl from file '%s' failed", file
);
600 cert
= lib
->creds
->create(lib
->creds
,
601 CRED_CERTIFICATE
, CERT_X509_AC
,
602 BUILD_FROM_FILE
, file
,
606 add_ac(this, (ac_t
*)cert
);
607 DBG1(DBG_CFG
, " loaded attribute certificate from "
612 DBG1(DBG_CFG
, " loading attribute certificate from "
613 "file '%s' failed", file
);
620 enumerator
->destroy(enumerator
);
624 * Implementation of credential_set_t.cache_cert.
626 static void cache_cert(private_stroke_cred_t
*this, certificate_t
*cert
)
628 if (cert
->get_type(cert
) == CERT_X509_CRL
&& this->cachecrl
)
630 /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
631 crl_t
*crl
= (crl_t
*)cert
;
634 if (add_crl(this, crl
))
639 chunk
= crl
->get_authKeyIdentifier(crl
);
640 hex
= chunk_to_hex(chunk
, NULL
, FALSE
);
641 snprintf(buf
, sizeof(buf
), "%s/%s.crl", CRL_DIR
, hex
);
644 chunk
= cert
->get_encoding(cert
);
645 chunk_write(chunk
, buf
, "crl", 022, TRUE
);
652 * Implementation of stroke_cred_t.cachecrl.
654 static void cachecrl(private_stroke_cred_t
*this, bool enabled
)
656 DBG1(DBG_CFG
, "crl caching to %s %s",
657 CRL_DIR
, enabled
? "enabled" : "disabled");
658 this->cachecrl
= enabled
;
663 * Convert a string of characters into a binary secret
664 * A string between single or double quotes is treated as ASCII characters
665 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
667 static err_t
extract_secret(chunk_t
*secret
, chunk_t
*line
)
670 char delimiter
= ' ';
673 if (!eat_whitespace(line
))
675 return "missing secret";
678 if (*line
->ptr
== '\'' || *line
->ptr
== '"')
681 delimiter
= *line
->ptr
;
682 line
->ptr
++; line
->len
--;
685 if (!extract_token(&raw_secret
, delimiter
, line
))
687 if (delimiter
== ' ')
693 return "missing second delimiter";
699 /* treat as an ASCII string */
700 *secret
= chunk_clone(raw_secret
);
703 /* treat 0x as hex, 0s as base64 */
704 if (raw_secret
.len
> 2)
706 if (strncasecmp("0x", raw_secret
.ptr
, 2) == 0)
708 *secret
= chunk_from_hex(chunk_skip(raw_secret
, 2), NULL
);
711 if (strncasecmp("0s", raw_secret
.ptr
, 2) == 0)
713 *secret
= chunk_from_base64(chunk_skip(raw_secret
, 2), NULL
);
717 *secret
= chunk_clone(raw_secret
);
722 * Data to pass to passphrase_cb
725 /** socket we use for prompting */
727 /** private key file */
729 /** buffer for passphrase */
731 } passphrase_cb_data_t
;
734 * Passphrase callback to read from whack fd
736 chunk_t
passphrase_cb(passphrase_cb_data_t
*data
, int try)
738 chunk_t secret
= chunk_empty
;;
742 fprintf(data
->prompt
, "invalid passphrase, too many trials\n");
747 fprintf(data
->prompt
, "Private key '%s' is encrypted\n", data
->file
);
751 fprintf(data
->prompt
, "invalid passphrase\n");
753 fprintf(data
->prompt
, "Passphrase:\n");
754 if (fgets(data
->buf
, sizeof(data
->buf
), data
->prompt
))
756 secret
= chunk_create(data
->buf
, strlen(data
->buf
));
758 { /* trim appended \n */
766 * reload ipsec.secrets
768 static void load_secrets(private_stroke_cred_t
*this, char *file
, int level
,
773 chunk_t chunk
, src
, line
;
775 private_key_t
*private;
776 shared_key_t
*shared
;
778 DBG1(DBG_CFG
, "loading secrets from '%s'", file
);
780 fd
= fopen(file
, "r");
783 DBG1(DBG_CFG
, "opening secrets file '%s' failed");
787 /* TODO: do error checks */
788 fseek(fd
, 0, SEEK_END
);
789 chunk
.len
= ftell(fd
);
791 chunk
.ptr
= malloc(chunk
.len
);
792 bytes
= fread(chunk
.ptr
, 1, chunk
.len
, fd
);
796 this->lock
->write_lock(this->lock
);
799 /* flush secrets on non-recursive invocation */
800 while (this->shared
->remove_last(this->shared
,
801 (void**)&shared
) == SUCCESS
)
803 shared
->destroy(shared
);
805 while (this->private->remove_last(this->private,
806 (void**)&private) == SUCCESS
)
808 private->destroy(private);
812 while (fetchline(&src
, &line
))
815 shared_key_type_t type
;
819 if (!eat_whitespace(&line
))
823 if (line
.len
> strlen("include ") &&
824 strneq(line
.ptr
, "include ", strlen("include ")))
827 char **expanded
, *dir
, pattern
[PATH_MAX
];
830 if (level
> MAX_SECRETS_RECURSION
)
832 DBG1(DBG_CFG
, "maximum level of %d includes reached, ignored",
833 MAX_SECRETS_RECURSION
);
836 /* terminate filename by space */
837 line
= chunk_skip(line
, strlen("include "));
838 pos
= memchr(line
.ptr
, ' ', line
.len
);
841 line
.len
= pos
- line
.ptr
;
843 if (line
.len
&& line
.ptr
[0] == '/')
845 if (line
.len
+ 1 > sizeof(pattern
))
847 DBG1(DBG_CFG
, "include pattern too long, ignored");
850 snprintf(pattern
, sizeof(pattern
), "%.*s", line
.len
, line
.ptr
);
853 { /* use directory of current file if relative */
857 if (line
.len
+ 1 + strlen(dir
) + 1 > sizeof(pattern
))
859 DBG1(DBG_CFG
, "include pattern too long, ignored");
863 snprintf(pattern
, sizeof(pattern
), "%s/%.*s",
864 dir
, line
.len
, line
.ptr
);
867 if (glob(pattern
, GLOB_ERR
, NULL
, &buf
) != 0)
869 DBG1(DBG_CFG
, "expanding file expression '%s' failed", pattern
);
874 for (expanded
= buf
.gl_pathv
; *expanded
!= NULL
; expanded
++)
876 load_secrets(this, *expanded
, level
+ 1, prompt
);
883 if (line
.len
> 2 && strneq(": ", line
.ptr
, 2))
885 /* no ids, skip the ':' */
890 else if (extract_token_str(&ids
, " : ", &line
))
892 /* NULL terminate the extracted id string */
893 *(ids
.ptr
+ ids
.len
) = '\0';
897 DBG1(DBG_CFG
, "line %d: missing ' : ' separator", line_nr
);
901 if (!eat_whitespace(&line
) || !extract_token(&token
, ' ', &line
))
903 DBG1(DBG_CFG
, "line %d: missing token", line_nr
);
906 if (match("RSA", &token
) || match("ECDSA", &token
))
910 chunk_t secret
= chunk_empty
;
911 private_key_t
*key
= NULL
;
912 key_type_t key_type
= match("RSA", &token
) ? KEY_RSA
: KEY_ECDSA
;
914 err_t ugh
= extract_value(&filename
, &line
);
918 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
921 if (filename
.len
== 0)
923 DBG1(DBG_CFG
, "line %d: empty filename", line_nr
);
926 if (*filename
.ptr
== '/')
928 /* absolute path name */
929 snprintf(path
, sizeof(path
), "%.*s", filename
.len
, filename
.ptr
);
933 /* relative path name */
934 snprintf(path
, sizeof(path
), "%s/%.*s", PRIVATE_KEY_DIR
,
935 filename
.len
, filename
.ptr
);
938 /* check for optional passphrase */
939 if (eat_whitespace(&line
))
941 ugh
= extract_secret(&secret
, &line
);
944 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
948 if (secret
.len
== 7 && strneq(secret
.ptr
, "%prompt", 7))
952 passphrase_cb_data_t data
;
954 data
.prompt
= prompt
;
956 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
,
957 key_type
, BUILD_FROM_FILE
, path
,
958 BUILD_PASSPHRASE_CALLBACK
,
959 passphrase_cb
, &data
, BUILD_END
);
964 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, key_type
,
965 BUILD_FROM_FILE
, path
,
966 BUILD_PASSPHRASE
, secret
, BUILD_END
);
970 DBG1(DBG_CFG
, " loaded %N private key file '%s'",
971 key_type_names
, key
->get_type(key
), path
);
972 this->private->insert_last(this->private, key
);
976 DBG1(DBG_CFG
, " skipped private key file '%s'", path
);
978 chunk_clear(&secret
);
980 else if (match("PIN", &token
))
982 chunk_t sc
= chunk_empty
, secret
= chunk_empty
;
983 char smartcard
[32], keyid
[22], pin
[32];
987 err_t ugh
= extract_value(&sc
, &line
);
991 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
996 DBG1(DBG_CFG
, "line %d: expected %%smartcard specifier", line_nr
);
999 snprintf(smartcard
, sizeof(smartcard
), "%.*s", sc
.len
, sc
.ptr
);
1000 smartcard
[sizeof(smartcard
) - 1] = '\0';
1002 /* parse slot and key id. only two formats are supported.
1003 * first try %smartcard<slot>:<keyid> */
1004 if (sscanf(smartcard
, "%%smartcard%u:%s", &slot
, keyid
) == 2)
1006 snprintf(smartcard
, sizeof(smartcard
), "%u:%s", slot
, keyid
);
1008 /* then try %smartcard:<keyid> */
1009 else if (sscanf(smartcard
, "%%smartcard:%s", keyid
) == 1)
1011 snprintf(smartcard
, sizeof(smartcard
), "%s", keyid
);
1015 DBG1(DBG_CFG
, "line %d: the given %%smartcard specifier is not"
1016 " supported or invalid", line_nr
);
1020 if (!eat_whitespace(&line
))
1022 DBG1(DBG_CFG
, "line %d: expected PIN", line_nr
);
1025 ugh
= extract_secret(&secret
, &line
);
1028 DBG1(DBG_CFG
, "line %d: malformed PIN: %s", line_nr
, ugh
);
1031 snprintf(pin
, sizeof(pin
), "%.*s", secret
.len
, secret
.ptr
);
1032 pin
[sizeof(pin
) - 1] = '\0';
1034 /* we assume an RSA key */
1035 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, KEY_RSA
,
1036 BUILD_SMARTCARD_KEYID
, smartcard
,
1037 BUILD_SMARTCARD_PIN
, pin
, BUILD_END
);
1041 DBG1(DBG_CFG
, " loaded private key from %.*s", sc
.len
, sc
.ptr
);
1042 this->private->insert_last(this->private, key
);
1044 memset(pin
, 0, sizeof(pin
));
1045 chunk_clear(&secret
);
1047 else if ((match("PSK", &token
) && (type
= SHARED_IKE
)) ||
1048 (match("EAP", &token
) && (type
= SHARED_EAP
)) ||
1049 (match("XAUTH", &token
) && (type
= SHARED_EAP
)))
1051 stroke_shared_key_t
*shared_key
;
1052 chunk_t secret
= chunk_empty
;
1055 err_t ugh
= extract_secret(&secret
, &line
);
1058 DBG1(DBG_CFG
, "line %d: malformed secret: %s", line_nr
, ugh
);
1061 shared_key
= stroke_shared_key_create(type
, secret
);
1062 DBG1(DBG_CFG
, " loaded %N secret for %s", shared_key_type_names
, type
,
1063 ids
.len
> 0 ? (char*)ids
.ptr
: "%any");
1064 DBG4(DBG_CFG
, " secret: %#B", &secret
);
1066 this->shared
->insert_last(this->shared
, shared_key
);
1070 identification_t
*peer_id
;
1072 ugh
= extract_value(&id
, &ids
);
1075 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1083 /* NULL terminate the ID string */
1084 *(id
.ptr
+ id
.len
) = '\0';
1085 peer_id
= identification_create_from_string(id
.ptr
);
1086 if (peer_id
->get_type(peer_id
) == ID_ANY
)
1088 peer_id
->destroy(peer_id
);
1092 shared_key
->add_owner(shared_key
, peer_id
);
1097 shared_key
->add_owner(shared_key
,
1098 identification_create_from_encoding(ID_ANY
, chunk_empty
));
1103 DBG1(DBG_CFG
, "line %d: token must be either "
1104 "RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr
);
1109 this->lock
->unlock(this->lock
);
1110 chunk_clear(&chunk
);
1114 * load all certificates from ipsec.d
1116 static void load_certs(private_stroke_cred_t
*this)
1118 DBG1(DBG_CFG
, "loading ca certificates from '%s'",
1119 CA_CERTIFICATE_DIR
);
1120 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1122 DBG1(DBG_CFG
, "loading aa certificates from '%s'",
1123 AA_CERTIFICATE_DIR
);
1124 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1126 DBG1(DBG_CFG
, "loading ocsp signer certificates from '%s'",
1127 OCSP_CERTIFICATE_DIR
);
1128 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
, X509_OCSP_SIGNER
);
1130 DBG1(DBG_CFG
, "loading attribute certificates from '%s'",
1131 ATTR_CERTIFICATE_DIR
);
1132 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1134 DBG1(DBG_CFG
, "loading crls from '%s'",
1136 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1140 * Implementation of stroke_cred_t.reread.
1142 static void reread(private_stroke_cred_t
*this, stroke_msg_t
*msg
, FILE *prompt
)
1144 if (msg
->reread
.flags
& REREAD_SECRETS
)
1146 DBG1(DBG_CFG
, "rereading secrets");
1147 load_secrets(this, SECRETS_FILE
, 0, prompt
);
1149 if (msg
->reread
.flags
& REREAD_CACERTS
)
1151 DBG1(DBG_CFG
, "rereading ca certificates from '%s'",
1152 CA_CERTIFICATE_DIR
);
1153 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1155 if (msg
->reread
.flags
& REREAD_OCSPCERTS
)
1157 DBG1(DBG_CFG
, "rereading ocsp signer certificates from '%s'",
1158 OCSP_CERTIFICATE_DIR
);
1159 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
,
1162 if (msg
->reread
.flags
& REREAD_AACERTS
)
1164 DBG1(DBG_CFG
, "rereading aa certificates from '%s'",
1165 AA_CERTIFICATE_DIR
);
1166 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1168 if (msg
->reread
.flags
& REREAD_ACERTS
)
1170 DBG1(DBG_CFG
, "rereading attribute certificates from '%s'",
1171 ATTR_CERTIFICATE_DIR
);
1172 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1174 if (msg
->reread
.flags
& REREAD_CRLS
)
1176 DBG1(DBG_CFG
, "rereading crls from '%s'",
1178 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1183 * Implementation of stroke_cred_t.destroy
1185 static void destroy(private_stroke_cred_t
*this)
1187 this->certs
->destroy_offset(this->certs
, offsetof(certificate_t
, destroy
));
1188 this->shared
->destroy_offset(this->shared
, offsetof(shared_key_t
, destroy
));
1189 this->private->destroy_offset(this->private, offsetof(private_key_t
, destroy
));
1190 this->lock
->destroy(this->lock
);
1197 stroke_cred_t
*stroke_cred_create()
1199 private_stroke_cred_t
*this = malloc_thing(private_stroke_cred_t
);
1201 this->public.set
.create_private_enumerator
= (void*)create_private_enumerator
;
1202 this->public.set
.create_cert_enumerator
= (void*)create_cert_enumerator
;
1203 this->public.set
.create_shared_enumerator
= (void*)create_shared_enumerator
;
1204 this->public.set
.create_cdp_enumerator
= (void*)return_null
;
1205 this->public.set
.cache_cert
= (void*)cache_cert
;
1206 this->public.reread
= (void(*)(stroke_cred_t
*, stroke_msg_t
*msg
, FILE*))reread
;
1207 this->public.load_ca
= (certificate_t
*(*)(stroke_cred_t
*, char *filename
))load_ca
;
1208 this->public.load_peer
= (certificate_t
*(*)(stroke_cred_t
*, char *filename
))load_peer
;
1209 this->public.cachecrl
= (void(*)(stroke_cred_t
*, bool enabled
))cachecrl
;
1210 this->public.destroy
= (void(*)(stroke_cred_t
*))destroy
;
1212 this->certs
= linked_list_create();
1213 this->shared
= linked_list_create();
1214 this->private = linked_list_create();
1215 this->lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
);
1218 load_secrets(this, SECRETS_FILE
, 0, NULL
);
1220 this->cachecrl
= FALSE
;
1222 return &this->public;