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 <threading/rwlock.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;
91 certificate_type_t type
;
95 * destroy id enumerator data and unlock list
97 static void id_data_destroy(id_data_t
*data
)
99 data
->this->lock
->unlock(data
->this->lock
);
104 * filter function for private key enumerator
106 static bool private_filter(id_data_t
*data
,
107 private_key_t
**in
, private_key_t
**out
)
112 if (data
->id
== NULL
)
117 if (key
->has_fingerprint(key
, data
->id
->get_encoding(data
->id
)))
126 * Implements credential_set_t.create_private_enumerator
128 static enumerator_t
* create_private_enumerator(private_stroke_cred_t
*this,
129 key_type_t type
, identification_t
*id
)
133 data
= malloc_thing(id_data_t
);
137 this->lock
->read_lock(this->lock
);
138 return enumerator_create_filter(this->private->create_enumerator(this->private),
139 (void*)private_filter
, data
,
140 (void*)id_data_destroy
);
144 * filter function for certs enumerator
146 static bool certs_filter(id_data_t
*data
, certificate_t
**in
, certificate_t
**out
)
148 public_key_t
*public;
149 certificate_t
*cert
= *in
;
151 if (data
->type
!= CERT_ANY
&& data
->type
!= cert
->get_type(cert
))
155 if (data
->id
== NULL
|| cert
->has_subject(cert
, data
->id
))
161 public = cert
->get_public_key(cert
);
164 if (public->has_fingerprint(public, data
->id
->get_encoding(data
->id
)))
166 public->destroy(public);
170 public->destroy(public);
176 * Implements credential_set_t.create_cert_enumerator
178 static enumerator_t
* create_cert_enumerator(private_stroke_cred_t
*this,
179 certificate_type_t cert
, key_type_t key
,
180 identification_t
*id
, bool trusted
)
184 if (trusted
&& (cert
== CERT_X509_CRL
|| cert
== CERT_X509_AC
))
188 data
= malloc_thing(id_data_t
);
193 this->lock
->read_lock(this->lock
);
194 return enumerator_create_filter(this->certs
->create_enumerator(this->certs
),
195 (void*)certs_filter
, data
,
196 (void*)id_data_destroy
);
200 private_stroke_cred_t
*this;
201 identification_t
*me
;
202 identification_t
*other
;
203 shared_key_type_t type
;
207 * free shared key enumerator data and unlock list
209 static void shared_data_destroy(shared_data_t
*data
)
211 data
->this->lock
->unlock(data
->this->lock
);
216 * filter function for certs enumerator
218 static bool shared_filter(shared_data_t
*data
,
219 stroke_shared_key_t
**in
, shared_key_t
**out
,
220 void **unused1
, id_match_t
*me
,
221 void **unused2
, id_match_t
*other
)
223 id_match_t my_match
= ID_MATCH_NONE
, other_match
= ID_MATCH_NONE
;
224 stroke_shared_key_t
*stroke
= *in
;
225 shared_key_t
*shared
= &stroke
->shared
;
227 if (data
->type
!= SHARED_ANY
&& shared
->get_type(shared
) != data
->type
)
234 my_match
= stroke
->has_owner(stroke
, data
->me
);
238 other_match
= stroke
->has_owner(stroke
, data
->other
);
240 if ((data
->me
|| data
->other
) && (!my_match
&& !other_match
))
251 *other
= other_match
;
257 * Implements credential_set_t.create_shared_enumerator
259 static enumerator_t
* create_shared_enumerator(private_stroke_cred_t
*this,
260 shared_key_type_t type
, identification_t
*me
,
261 identification_t
*other
)
263 shared_data_t
*data
= malloc_thing(shared_data_t
);
269 this->lock
->read_lock(this->lock
);
270 return enumerator_create_filter(this->shared
->create_enumerator(this->shared
),
271 (void*)shared_filter
, data
,
272 (void*)shared_data_destroy
);
276 * Add a certificate to chain
278 static certificate_t
* add_cert(private_stroke_cred_t
*this, certificate_t
*cert
)
280 certificate_t
*current
;
281 enumerator_t
*enumerator
;
284 this->lock
->read_lock(this->lock
);
285 enumerator
= this->certs
->create_enumerator(this->certs
);
286 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
288 if (current
->equals(current
, cert
))
290 /* cert already in queue */
297 enumerator
->destroy(enumerator
);
301 this->certs
->insert_last(this->certs
, cert
);
303 this->lock
->unlock(this->lock
);
308 * Implementation of stroke_cred_t.load_ca.
310 static certificate_t
* load_ca(private_stroke_cred_t
*this, char *filename
)
315 if (*filename
== '/')
317 snprintf(path
, sizeof(path
), "%s", filename
);
321 snprintf(path
, sizeof(path
), "%s/%s", CA_CERTIFICATE_DIR
, filename
);
324 cert
= lib
->creds
->create(lib
->creds
,
325 CRED_CERTIFICATE
, CERT_X509
,
326 BUILD_FROM_FILE
, path
,
330 x509_t
*x509
= (x509_t
*)cert
;
332 if (!(x509
->get_flags(x509
) & X509_CA
))
334 DBG1(DBG_CFG
, " ca certificate \"%Y\" misses ca basic constraint, "
335 "discarded", cert
->get_subject(cert
));
339 return (certificate_t
*)add_cert(this, cert
);
345 * Add X.509 CRL to chain
347 static bool add_crl(private_stroke_cred_t
*this, crl_t
* crl
)
349 certificate_t
*current
, *cert
= &crl
->certificate
;
350 enumerator_t
*enumerator
;
351 bool new = TRUE
, found
= FALSE
;
353 this->lock
->write_lock(this->lock
);
354 enumerator
= this->certs
->create_enumerator(this->certs
);
355 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
357 if (current
->get_type(current
) == CERT_X509_CRL
)
359 crl_t
*crl_c
= (crl_t
*)current
;
360 chunk_t authkey
= crl
->get_authKeyIdentifier(crl
);
361 chunk_t authkey_c
= crl_c
->get_authKeyIdentifier(crl_c
);
363 /* if compare authorityKeyIdentifiers if available */
364 if (authkey
.ptr
&& authkey_c
.ptr
&& chunk_equals(authkey
, authkey_c
))
370 identification_t
*issuer
= cert
->get_issuer(cert
);
371 identification_t
*issuer_c
= current
->get_issuer(current
);
373 /* otherwise compare issuer distinguished names */
374 if (issuer
->equals(issuer
, issuer_c
))
381 new = cert
->is_newer(cert
, current
);
384 this->certs
->remove_at(this->certs
, enumerator
);
394 enumerator
->destroy(enumerator
);
398 this->certs
->insert_last(this->certs
, cert
);
400 this->lock
->unlock(this->lock
);
405 * Add X.509 attribute certificate to chain
407 static bool add_ac(private_stroke_cred_t
*this, ac_t
* ac
)
409 certificate_t
*cert
= &ac
->certificate
;
411 this->lock
->write_lock(this->lock
);
412 this->certs
->insert_last(this->certs
, cert
);
413 this->lock
->unlock(this->lock
);
418 * Implementation of stroke_cred_t.load_peer.
420 static certificate_t
* load_peer(private_stroke_cred_t
*this, char *filename
)
425 if (*filename
== '/')
427 snprintf(path
, sizeof(path
), "%s", filename
);
431 snprintf(path
, sizeof(path
), "%s/%s", CERTIFICATE_DIR
, filename
);
434 cert
= lib
->creds
->create(lib
->creds
,
435 CRED_CERTIFICATE
, CERT_ANY
,
436 BUILD_FROM_FILE
, path
,
440 cert
= add_cert(this, cert
);
441 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
442 cert
->get_subject(cert
), filename
);
443 return cert
->get_ref(cert
);
445 DBG1(DBG_CFG
, " loading certificate from '%s' failed", filename
);
450 * load trusted certificates from a directory
452 static void load_certdir(private_stroke_cred_t
*this, char *path
,
453 certificate_type_t type
, x509_flag_t flag
)
458 enumerator_t
*enumerator
= enumerator_create_directory(path
);
462 DBG1(DBG_CFG
, " reading directory failed");
466 while (enumerator
->enumerate(enumerator
, NULL
, &file
, &st
))
470 if (!S_ISREG(st
.st_mode
))
472 /* skip special file */
479 { /* for CA certificates, we strictly require
480 * the CA basic constraint to be set */
481 cert
= lib
->creds
->create(lib
->creds
,
482 CRED_CERTIFICATE
, CERT_X509
,
483 BUILD_FROM_FILE
, file
, BUILD_END
);
486 x509_t
*x509
= (x509_t
*)cert
;
488 if (!(x509
->get_flags(x509
) & X509_CA
))
490 DBG1(DBG_CFG
, " ca certificate \"%Y\" lacks "
491 "ca basic constraint, discarded",
492 cert
->get_subject(cert
));
498 DBG1(DBG_CFG
, " loaded ca certificate \"%Y\" from '%s'",
499 cert
->get_subject(cert
), file
);
504 DBG1(DBG_CFG
, " loading ca certificate from '%s' "
509 { /* for all other flags, we add them to the certificate. */
510 cert
= lib
->creds
->create(lib
->creds
,
511 CRED_CERTIFICATE
, CERT_X509
,
512 BUILD_FROM_FILE
, file
,
513 BUILD_X509_FLAG
, flag
, BUILD_END
);
516 DBG1(DBG_CFG
, " loaded certificate \"%Y\" from '%s'",
517 cert
->get_subject(cert
), file
);
521 DBG1(DBG_CFG
, " loading certificate from '%s' "
527 add_cert(this, cert
);
531 cert
= lib
->creds
->create(lib
->creds
,
532 CRED_CERTIFICATE
, CERT_X509_CRL
,
533 BUILD_FROM_FILE
, file
,
537 add_crl(this, (crl_t
*)cert
);
538 DBG1(DBG_CFG
, " loaded crl from '%s'", file
);
542 DBG1(DBG_CFG
, " loading crl from '%s' failed", file
);
546 cert
= lib
->creds
->create(lib
->creds
,
547 CRED_CERTIFICATE
, CERT_X509_AC
,
548 BUILD_FROM_FILE
, file
,
552 add_ac(this, (ac_t
*)cert
);
553 DBG1(DBG_CFG
, " loaded attribute certificate from '%s'",
558 DBG1(DBG_CFG
, " loading attribute certificate from '%s' "
566 enumerator
->destroy(enumerator
);
570 * Implementation of credential_set_t.cache_cert.
572 static void cache_cert(private_stroke_cred_t
*this, certificate_t
*cert
)
574 if (cert
->get_type(cert
) == CERT_X509_CRL
&& this->cachecrl
)
576 /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
577 crl_t
*crl
= (crl_t
*)cert
;
580 if (add_crl(this, crl
))
585 chunk
= crl
->get_authKeyIdentifier(crl
);
586 hex
= chunk_to_hex(chunk
, NULL
, FALSE
);
587 snprintf(buf
, sizeof(buf
), "%s/%s.crl", CRL_DIR
, hex
);
590 chunk
= cert
->get_encoding(cert
);
591 chunk_write(chunk
, buf
, "crl", 022, TRUE
);
598 * Implementation of stroke_cred_t.cachecrl.
600 static void cachecrl(private_stroke_cred_t
*this, bool enabled
)
602 DBG1(DBG_CFG
, "crl caching to %s %s",
603 CRL_DIR
, enabled ?
"enabled" : "disabled");
604 this->cachecrl
= enabled
;
609 * Convert a string of characters into a binary secret
610 * A string between single or double quotes is treated as ASCII characters
611 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
613 static err_t
extract_secret(chunk_t
*secret
, chunk_t
*line
)
616 char delimiter
= ' ';
619 if (!eat_whitespace(line
))
621 return "missing secret";
624 if (*line
->ptr
== '\'' || *line
->ptr
== '"')
627 delimiter
= *line
->ptr
;
628 line
->ptr
++; line
->len
--;
631 if (!extract_token(&raw_secret
, delimiter
, line
))
633 if (delimiter
== ' ')
639 return "missing second delimiter";
645 /* treat as an ASCII string */
646 *secret
= chunk_clone(raw_secret
);
649 /* treat 0x as hex, 0s as base64 */
650 if (raw_secret
.len
> 2)
652 if (strncasecmp("0x", raw_secret
.ptr
, 2) == 0)
654 *secret
= chunk_from_hex(chunk_skip(raw_secret
, 2), NULL
);
657 if (strncasecmp("0s", raw_secret
.ptr
, 2) == 0)
659 *secret
= chunk_from_base64(chunk_skip(raw_secret
, 2), NULL
);
663 *secret
= chunk_clone(raw_secret
);
668 * Data to pass to passphrase_cb
671 /** socket we use for prompting */
673 /** private key file */
675 /** buffer for passphrase */
677 } passphrase_cb_data_t
;
680 * Passphrase callback to read from whack fd
682 chunk_t
passphrase_cb(passphrase_cb_data_t
*data
, int try)
684 chunk_t secret
= chunk_empty
;;
688 fprintf(data
->prompt
, "invalid passphrase, too many trials\n");
693 fprintf(data
->prompt
, "Private key '%s' is encrypted\n", data
->file
);
697 fprintf(data
->prompt
, "invalid passphrase\n");
699 fprintf(data
->prompt
, "Passphrase:\n");
700 if (fgets(data
->buf
, sizeof(data
->buf
), data
->prompt
))
702 secret
= chunk_create(data
->buf
, strlen(data
->buf
));
704 { /* trim appended \n */
712 * reload ipsec.secrets
714 static void load_secrets(private_stroke_cred_t
*this, char *file
, int level
,
719 chunk_t chunk
, src
, line
;
721 private_key_t
*private;
722 shared_key_t
*shared
;
724 DBG1(DBG_CFG
, "loading secrets from '%s'", file
);
726 fd
= fopen(file
, "r");
729 DBG1(DBG_CFG
, "opening secrets file '%s' failed", file
);
733 /* TODO: do error checks */
734 fseek(fd
, 0, SEEK_END
);
735 chunk
.len
= ftell(fd
);
737 chunk
.ptr
= malloc(chunk
.len
);
738 bytes
= fread(chunk
.ptr
, 1, chunk
.len
, fd
);
744 this->lock
->write_lock(this->lock
);
746 /* flush secrets on non-recursive invocation */
747 while (this->shared
->remove_last(this->shared
,
748 (void**)&shared
) == SUCCESS
)
750 shared
->destroy(shared
);
752 while (this->private->remove_last(this->private,
753 (void**)&private) == SUCCESS
)
755 private->destroy(private);
759 while (fetchline(&src
, &line
))
762 shared_key_type_t type
;
766 if (!eat_whitespace(&line
))
770 if (line
.len
> strlen("include ") &&
771 strneq(line
.ptr
, "include ", strlen("include ")))
774 char **expanded
, *dir
, pattern
[PATH_MAX
];
777 if (level
> MAX_SECRETS_RECURSION
)
779 DBG1(DBG_CFG
, "maximum level of %d includes reached, ignored",
780 MAX_SECRETS_RECURSION
);
783 /* terminate filename by space */
784 line
= chunk_skip(line
, strlen("include "));
785 pos
= memchr(line
.ptr
, ' ', line
.len
);
788 line
.len
= pos
- line
.ptr
;
790 if (line
.len
&& line
.ptr
[0] == '/')
792 if (line
.len
+ 1 > sizeof(pattern
))
794 DBG1(DBG_CFG
, "include pattern too long, ignored");
797 snprintf(pattern
, sizeof(pattern
), "%.*s", line
.len
, line
.ptr
);
800 { /* use directory of current file if relative */
804 if (line
.len
+ 1 + strlen(dir
) + 1 > sizeof(pattern
))
806 DBG1(DBG_CFG
, "include pattern too long, ignored");
810 snprintf(pattern
, sizeof(pattern
), "%s/%.*s",
811 dir
, line
.len
, line
.ptr
);
814 if (glob(pattern
, GLOB_ERR
, NULL
, &buf
) != 0)
816 DBG1(DBG_CFG
, "expanding file expression '%s' failed", pattern
);
821 for (expanded
= buf
.gl_pathv
; *expanded
!= NULL
; expanded
++)
823 load_secrets(this, *expanded
, level
+ 1, prompt
);
830 if (line
.len
> 2 && strneq(": ", line
.ptr
, 2))
832 /* no ids, skip the ':' */
837 else if (extract_token_str(&ids
, " : ", &line
))
839 /* NULL terminate the extracted id string */
840 *(ids
.ptr
+ ids
.len
) = '\0';
844 DBG1(DBG_CFG
, "line %d: missing ' : ' separator", line_nr
);
848 if (!eat_whitespace(&line
) || !extract_token(&token
, ' ', &line
))
850 DBG1(DBG_CFG
, "line %d: missing token", line_nr
);
853 if (match("RSA", &token
) || match("ECDSA", &token
))
857 chunk_t secret
= chunk_empty
;
858 private_key_t
*key
= NULL
;
859 key_type_t key_type
= match("RSA", &token
) ? KEY_RSA
: KEY_ECDSA
;
861 err_t ugh
= extract_value(&filename
, &line
);
865 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
868 if (filename
.len
== 0)
870 DBG1(DBG_CFG
, "line %d: empty filename", line_nr
);
873 if (*filename
.ptr
== '/')
875 /* absolute path name */
876 snprintf(path
, sizeof(path
), "%.*s", filename
.len
, filename
.ptr
);
880 /* relative path name */
881 snprintf(path
, sizeof(path
), "%s/%.*s", PRIVATE_KEY_DIR
,
882 filename
.len
, filename
.ptr
);
885 /* check for optional passphrase */
886 if (eat_whitespace(&line
))
888 ugh
= extract_secret(&secret
, &line
);
891 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
895 if (secret
.len
== 7 && strneq(secret
.ptr
, "%prompt", 7))
899 passphrase_cb_data_t data
;
901 data
.prompt
= prompt
;
903 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
,
904 key_type
, BUILD_FROM_FILE
, path
,
905 BUILD_PASSPHRASE_CALLBACK
,
906 passphrase_cb
, &data
, BUILD_END
);
911 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, key_type
,
912 BUILD_FROM_FILE
, path
,
913 BUILD_PASSPHRASE
, secret
, BUILD_END
);
917 DBG1(DBG_CFG
, " loaded %N private key from '%s'",
918 key_type_names
, key
->get_type(key
), path
);
919 this->private->insert_last(this->private, key
);
923 DBG1(DBG_CFG
, " loading private key from '%s' failed", path
);
925 chunk_clear(&secret
);
927 else if (match("PIN", &token
))
929 chunk_t sc
= chunk_empty
, secret
= chunk_empty
;
930 char smartcard
[32], keyid
[22], pin
[32];
934 err_t ugh
= extract_value(&sc
, &line
);
938 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
943 DBG1(DBG_CFG
, "line %d: expected %%smartcard specifier", line_nr
);
946 snprintf(smartcard
, sizeof(smartcard
), "%.*s", sc
.len
, sc
.ptr
);
947 smartcard
[sizeof(smartcard
) - 1] = '\0';
949 /* parse slot and key id. only two formats are supported.
950 * first try %smartcard<slot>:<keyid> */
951 if (sscanf(smartcard
, "%%smartcard%u:%s", &slot
, keyid
) == 2)
953 snprintf(smartcard
, sizeof(smartcard
), "%u:%s", slot
, keyid
);
955 /* then try %smartcard:<keyid> */
956 else if (sscanf(smartcard
, "%%smartcard:%s", keyid
) == 1)
958 snprintf(smartcard
, sizeof(smartcard
), "%s", keyid
);
962 DBG1(DBG_CFG
, "line %d: the given %%smartcard specifier is not"
963 " supported or invalid", line_nr
);
967 if (!eat_whitespace(&line
))
969 DBG1(DBG_CFG
, "line %d: expected PIN", line_nr
);
972 ugh
= extract_secret(&secret
, &line
);
975 DBG1(DBG_CFG
, "line %d: malformed PIN: %s", line_nr
, ugh
);
978 snprintf(pin
, sizeof(pin
), "%.*s", secret
.len
, secret
.ptr
);
979 pin
[sizeof(pin
) - 1] = '\0';
981 /* we assume an RSA key */
982 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, KEY_RSA
,
983 BUILD_SMARTCARD_KEYID
, smartcard
,
984 BUILD_SMARTCARD_PIN
, pin
, BUILD_END
);
988 DBG1(DBG_CFG
, " loaded private key from %.*s", sc
.len
, sc
.ptr
);
989 this->private->insert_last(this->private, key
);
991 memset(pin
, 0, sizeof(pin
));
992 chunk_clear(&secret
);
994 else if ((match("PSK", &token
) && (type
= SHARED_IKE
)) ||
995 (match("EAP", &token
) && (type
= SHARED_EAP
)) ||
996 (match("NTLM", &token
) && (type
= SHARED_NT_HASH
)) ||
997 (match("XAUTH", &token
) && (type
= SHARED_EAP
)))
999 stroke_shared_key_t
*shared_key
;
1000 chunk_t secret
= chunk_empty
;
1003 err_t ugh
= extract_secret(&secret
, &line
);
1006 DBG1(DBG_CFG
, "line %d: malformed secret: %s", line_nr
, ugh
);
1009 shared_key
= stroke_shared_key_create(type
, secret
);
1010 DBG1(DBG_CFG
, " loaded %N secret for %s", shared_key_type_names
, type
,
1011 ids
.len
> 0 ?
(char*)ids
.ptr
: "%any");
1012 DBG4(DBG_CFG
, " secret: %#B", &secret
);
1014 this->shared
->insert_last(this->shared
, shared_key
);
1018 identification_t
*peer_id
;
1020 ugh
= extract_value(&id
, &ids
);
1023 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1031 /* NULL terminate the ID string */
1032 *(id
.ptr
+ id
.len
) = '\0';
1033 peer_id
= identification_create_from_string(id
.ptr
);
1034 if (peer_id
->get_type(peer_id
) == ID_ANY
)
1036 peer_id
->destroy(peer_id
);
1040 shared_key
->add_owner(shared_key
, peer_id
);
1045 shared_key
->add_owner(shared_key
,
1046 identification_create_from_encoding(ID_ANY
, chunk_empty
));
1051 DBG1(DBG_CFG
, "line %d: token must be either "
1052 "RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr
);
1059 this->lock
->unlock(this->lock
);
1061 chunk_clear(&chunk
);
1065 * load all certificates from ipsec.d
1067 static void load_certs(private_stroke_cred_t
*this)
1069 DBG1(DBG_CFG
, "loading ca certificates from '%s'",
1070 CA_CERTIFICATE_DIR
);
1071 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1073 DBG1(DBG_CFG
, "loading aa certificates from '%s'",
1074 AA_CERTIFICATE_DIR
);
1075 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1077 DBG1(DBG_CFG
, "loading ocsp signer certificates from '%s'",
1078 OCSP_CERTIFICATE_DIR
);
1079 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
, X509_OCSP_SIGNER
);
1081 DBG1(DBG_CFG
, "loading attribute certificates from '%s'",
1082 ATTR_CERTIFICATE_DIR
);
1083 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1085 DBG1(DBG_CFG
, "loading crls from '%s'",
1087 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1091 * Implementation of stroke_cred_t.reread.
1093 static void reread(private_stroke_cred_t
*this, stroke_msg_t
*msg
, FILE *prompt
)
1095 if (msg
->reread
.flags
& REREAD_SECRETS
)
1097 DBG1(DBG_CFG
, "rereading secrets");
1098 load_secrets(this, SECRETS_FILE
, 0, prompt
);
1100 if (msg
->reread
.flags
& REREAD_CACERTS
)
1102 DBG1(DBG_CFG
, "rereading ca certificates from '%s'",
1103 CA_CERTIFICATE_DIR
);
1104 load_certdir(this, CA_CERTIFICATE_DIR
, CERT_X509
, X509_CA
);
1106 if (msg
->reread
.flags
& REREAD_OCSPCERTS
)
1108 DBG1(DBG_CFG
, "rereading ocsp signer certificates from '%s'",
1109 OCSP_CERTIFICATE_DIR
);
1110 load_certdir(this, OCSP_CERTIFICATE_DIR
, CERT_X509
,
1113 if (msg
->reread
.flags
& REREAD_AACERTS
)
1115 DBG1(DBG_CFG
, "rereading aa certificates from '%s'",
1116 AA_CERTIFICATE_DIR
);
1117 load_certdir(this, AA_CERTIFICATE_DIR
, CERT_X509
, X509_AA
);
1119 if (msg
->reread
.flags
& REREAD_ACERTS
)
1121 DBG1(DBG_CFG
, "rereading attribute certificates from '%s'",
1122 ATTR_CERTIFICATE_DIR
);
1123 load_certdir(this, ATTR_CERTIFICATE_DIR
, CERT_X509_AC
, 0);
1125 if (msg
->reread
.flags
& REREAD_CRLS
)
1127 DBG1(DBG_CFG
, "rereading crls from '%s'",
1129 load_certdir(this, CRL_DIR
, CERT_X509_CRL
, 0);
1134 * Implementation of stroke_cred_t.destroy
1136 static void destroy(private_stroke_cred_t
*this)
1138 this->certs
->destroy_offset(this->certs
, offsetof(certificate_t
, destroy
));
1139 this->shared
->destroy_offset(this->shared
, offsetof(shared_key_t
, destroy
));
1140 this->private->destroy_offset(this->private, offsetof(private_key_t
, destroy
));
1141 this->lock
->destroy(this->lock
);
1148 stroke_cred_t
*stroke_cred_create()
1150 private_stroke_cred_t
*this = malloc_thing(private_stroke_cred_t
);
1152 this->public.set
.create_private_enumerator
= (void*)create_private_enumerator
;
1153 this->public.set
.create_cert_enumerator
= (void*)create_cert_enumerator
;
1154 this->public.set
.create_shared_enumerator
= (void*)create_shared_enumerator
;
1155 this->public.set
.create_cdp_enumerator
= (void*)return_null
;
1156 this->public.set
.cache_cert
= (void*)cache_cert
;
1157 this->public.reread
= (void(*)(stroke_cred_t
*, stroke_msg_t
*msg
, FILE*))reread
;
1158 this->public.load_ca
= (certificate_t
*(*)(stroke_cred_t
*, char *filename
))load_ca
;
1159 this->public.load_peer
= (certificate_t
*(*)(stroke_cred_t
*, char *filename
))load_peer
;
1160 this->public.cachecrl
= (void(*)(stroke_cred_t
*, bool enabled
))cachecrl
;
1161 this->public.destroy
= (void(*)(stroke_cred_t
*))destroy
;
1163 this->certs
= linked_list_create();
1164 this->shared
= linked_list_create();
1165 this->private = linked_list_create();
1166 this->lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
);
1169 load_secrets(this, SECRETS_FILE
, 0, NULL
);
1171 this->cachecrl
= FALSE
;
1173 return &this->public;