support of multiple certificates with same peer id
[strongswan.git] / src / charon / config / credentials / local_credential_store.c
1 /**
2 * @file local_credential_store.c
3 *
4 * @brief Implementation of local_credential_store_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <sys/stat.h>
24 #include <dirent.h>
25 #include <string.h>
26 #include <pthread.h>
27 #include <errno.h>
28
29 #include <library.h>
30 #include <utils/lexparser.h>
31 #include <utils/linked_list.h>
32 #include <crypto/rsa/rsa_public_key.h>
33 #include <crypto/certinfo.h>
34 #include <crypto/x509.h>
35 #include <crypto/ca.h>
36 #include <crypto/ac.h>
37 #include <crypto/crl.h>
38 #include <asn1/ttodata.h>
39
40 #include "local_credential_store.h"
41
42 #define PATH_BUF 256
43 #define MAX_CA_PATH_LEN 7
44
45 typedef struct shared_key_t shared_key_t;
46
47 /**
48 * Private date of a shared_key_t object
49 */
50 struct shared_key_t {
51
52 /**
53 * shared secret
54 */
55 chunk_t secret;
56
57 /**
58 * list of peer IDs
59 */
60 linked_list_t *peers;
61 };
62
63
64 /**
65 * Implementation of shared_key_t.destroy.
66 */
67 static void shared_key_destroy(shared_key_t *this)
68 {
69 this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
70 chunk_free(&this->secret);
71 free(this);
72 }
73
74 /**
75 * @brief Creates a shared_key_t object.
76 *
77 * @param shared_key shared key value
78 * @return shared_key_t object
79 *
80 * @ingroup config
81 */
82 static shared_key_t *shared_key_create(chunk_t secret)
83 {
84 shared_key_t *this = malloc_thing(shared_key_t);
85
86 /* private data */
87 this->secret = chunk_clone(secret);
88 this->peers = linked_list_create();
89
90 return (this);
91 }
92
93 /* ------------------------------------------------------------------------ *
94 * the ca_info_t object as a central control element
95
96 +--------------------------------------------------------+
97 | local_credential_store_t |
98 +--------------------------------------------------------+
99 | |
100 +---------------------------+ +-------------------------+
101 | linked_list_t *auth_certs | | linked_list_t *ca_infos |
102 +---------------------------+ +-------------------------+
103 | |
104 | +------------------------- +
105 | | ca_info_t |
106 | +--------------------------+
107 +---------------+ | char *name |
108 | x509_t |<--| x509_t *cacert |
109 +---------------+ | linked_list_t *attrcerts | +----------------------+
110 | chunk_t keyid | | linked_list_t *certinfos |-->| certinfo_t |
111 +---------------+ | linked_list_t *ocspuris | +----------------------+
112 | | crl_t *crl | | chunk_t serialNumber |
113 | | linked_list_t *crluris | | cert_status_t status |
114 +---------------+ | pthread_mutex_t mutex | | time_t thisUpdate |
115 | x509_t | +--------------------------+ | time_t nextUpdate |
116 +---------------+ | | bool once |
117 | chunk_t keyid | | +----------------------+
118 +---------------+ +------------------------- + |
119 | | ca_info_t | +----------------------+
120 | +--------------------------+ | certinfo_t |
121 +---------------+ | char *name | +----------------------+
122 | x509_t |<--| x509_t *cacert | | chunk_t serialNumber |
123 +---------------+ | linked_list_t *attrcerts | | cert_status_t status |
124 | chunk_t keyid | | linked_list_t *certinfos | | time_t thisUpdate |
125 +---------------+ | linked_list_t *ocspuris | | time_t nextUpdate |
126 | | crl_t *crl | | bool once |
127 | | linked_list_t *crluris | +----------------------+
128 | | pthread_mutex_t mutex; | |
129 | +--------------------------+
130 | |
131
132 * ------------------------------------------------------------------------ */
133
134 typedef struct private_local_credential_store_t private_local_credential_store_t;
135
136 /**
137 * Private data of an local_credential_store_t object
138 */
139 struct private_local_credential_store_t {
140
141 /**
142 * Public part
143 */
144 local_credential_store_t public;
145
146 /**
147 * list of shared keys
148 */
149 linked_list_t *shared_keys;
150
151 /**
152 * list of EAP keys
153 */
154 linked_list_t *eap_keys;
155
156 /**
157 * list of key_entry_t's with private keys
158 */
159 linked_list_t *private_keys;
160
161 /**
162 * list of X.509 certificates with public keys
163 */
164 linked_list_t *certs;
165
166 /**
167 * list of X.509 authority certificates with public keys
168 */
169 linked_list_t *auth_certs;
170
171 /**
172 * list of X.509 CA information records
173 */
174 linked_list_t *ca_infos;
175 };
176
177
178 /**
179 * Get a key from a list with shared_key_t's
180 */
181 static status_t get_key(linked_list_t *keys,
182 identification_t *my_id,
183 identification_t *other_id, chunk_t *secret)
184 {
185 typedef enum {
186 PRIO_UNDEFINED= 0x00,
187 PRIO_ANY_MATCH= 0x01,
188 PRIO_MY_MATCH= 0x02,
189 PRIO_OTHER_MATCH= 0x04,
190 } prio_t;
191
192 prio_t best_prio = PRIO_UNDEFINED;
193 chunk_t found = chunk_empty;
194 shared_key_t *shared_key;
195
196 iterator_t *iterator = keys->create_iterator(keys, TRUE);
197
198 while (iterator->iterate(iterator, (void**)&shared_key))
199 {
200 iterator_t *peer_iterator;
201 identification_t *peer_id;
202 prio_t prio = PRIO_UNDEFINED;
203
204 peer_iterator = shared_key->peers->create_iterator(shared_key->peers, TRUE);
205
206 if (peer_iterator->get_count(peer_iterator) == 0)
207 {
208 /* this is a wildcard shared key */
209 prio = PRIO_ANY_MATCH;
210 }
211 else
212 {
213 while (peer_iterator->iterate(peer_iterator, (void**)&peer_id))
214 {
215 if (my_id->equals(my_id, peer_id))
216 {
217 prio |= PRIO_MY_MATCH;
218 }
219 if (other_id->equals(other_id, peer_id))
220 {
221 prio |= PRIO_OTHER_MATCH;
222 }
223 }
224 }
225 peer_iterator->destroy(peer_iterator);
226
227 if (prio > best_prio)
228 {
229 best_prio = prio;
230 found = shared_key->secret;
231 }
232 }
233 iterator->destroy(iterator);
234
235 if (best_prio == PRIO_UNDEFINED)
236 {
237 return NOT_FOUND;
238 }
239 else
240 {
241 *secret = chunk_clone(found);
242 return SUCCESS;
243 }
244 }
245
246
247 /**
248 * Implementation of local_credential_store_t.get_shared_key.
249 */
250 static status_t get_shared_key(private_local_credential_store_t *this,
251 identification_t *my_id,
252 identification_t *other_id, chunk_t *secret)
253 {
254 return get_key(this->shared_keys, my_id, other_id, secret);
255 }
256
257 /**
258 * Implementation of local_credential_store_t.get_eap_key.
259 */
260 static status_t get_eap_key(private_local_credential_store_t *this,
261 identification_t *my_id,
262 identification_t *other_id, chunk_t *secret)
263 {
264 return get_key(this->eap_keys, my_id, other_id, secret);
265 }
266
267 /**
268 * Implementation of credential_store_t.get_certificate.
269 */
270 static x509_t* get_certificate(private_local_credential_store_t *this,
271 identification_t *id)
272 {
273 x509_t *found = NULL;
274 x509_t *current_cert;
275
276 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
277
278 while (iterator->iterate(iterator, (void**)&current_cert))
279 {
280 if (id->equals(id, current_cert->get_subject(current_cert)) ||
281 current_cert->equals_subjectAltName(current_cert, id))
282 {
283 found = current_cert;
284 break;
285 }
286 }
287 iterator->destroy(iterator);
288 return found;
289 }
290
291 /**
292 * Implementation of local_credential_store_t.get_rsa_public_key.
293 */
294 static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this,
295 identification_t *id)
296 {
297 x509_t *cert = get_certificate(this, id);
298
299 return (cert == NULL)? NULL:cert->get_public_key(cert);
300 }
301
302 /**
303 * Implementation of credential_store_t.get_issuer.
304 */
305 static ca_info_t* get_issuer(private_local_credential_store_t *this, const x509_t *cert)
306 {
307 ca_info_t *found = NULL;
308 ca_info_t *ca_info;
309
310 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
311
312 while (iterator->iterate(iterator, (void**)&ca_info))
313 {
314 if (ca_info->is_cert_issuer(ca_info, cert))
315 {
316 found = ca_info;
317 break;
318 }
319 }
320 iterator->destroy(iterator);
321
322 return found;
323 }
324
325 /**
326 * Implementation of local_credential_store_t.verify.
327 */
328 static status_t verify_signature(private_local_credential_store_t *this,
329 chunk_t hash, chunk_t sig,
330 identification_t *id, ca_info_t **issuer_p)
331 {
332 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
333 status_t sig_status;
334 x509_t *cert;
335
336 /* default return values in case of failure */
337 sig_status = NOT_FOUND;
338 *issuer_p = NULL;
339
340 while (iterator->iterate(iterator, (void**)&cert))
341 {
342 if (id->equals(id, cert->get_subject(cert))
343 || cert->equals_subjectAltName(cert, id))
344 {
345 err_t ugh;
346 rsa_public_key_t *public_key = cert->get_public_key(cert);
347 chunk_t keyid = public_key->get_keyid(public_key);
348
349 DBG2(DBG_CFG, "found candidate peer certificate");
350 DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
351 DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
352 DBG2(DBG_CFG, "keyid: %#B", &keyid);
353
354 ugh = cert->is_valid(cert, NULL);
355 if (ugh != NULL)
356 {
357 DBG1(DBG_CFG, "candidate peer certificate %s", ugh);
358 sig_status = INVALID_STATE;
359 continue;
360 }
361 if (!cert->is_self_signed(cert))
362 {
363 cert_status_t cert_status;
364 ca_info_t *issuer = get_issuer(this, cert);
365
366 if (issuer == NULL)
367 {
368 DBG1(DBG_CFG, "issuer of candidate peer certificate not found");
369 sig_status = NOT_FOUND;
370 continue;
371 }
372 cert_status = cert->get_status(cert);
373
374 if (cert_status == CERT_REVOKED
375 || cert_status == CERT_UNTRUSTED
376 || ((issuer)->is_strict(issuer) && cert_status != CERT_GOOD))
377 {
378 DBG1(DBG_CFG, "candidate peer certificate has a non-acceptable status: %N", cert_status_names, cert_status);
379 sig_status = INVALID_STATE;
380 continue;
381 }
382 if (cert_status == CERT_GOOD && cert->get_until(cert) < time(NULL))
383 {
384 DBG1(DBG_CFG, "candidate peer certificate is good but crl is stale");
385 sig_status = INVALID_STATE;
386 continue;
387 }
388 *issuer_p = issuer;
389 }
390 sig_status = public_key->verify_emsa_pkcs1_signature(public_key, hash, sig);
391 if (sig_status == SUCCESS)
392 {
393 DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
394 break;
395 }
396 else
397 {
398 DBG1(DBG_CFG, "candidate peer certificate has a non-matching RSA public key");
399 *issuer_p = NULL;
400 }
401 }
402 }
403 iterator->destroy(iterator);
404 if (sig_status == NOT_FOUND)
405 {
406 DBG1(DBG_CFG, "no candidate peer certificate found");
407 }
408 return sig_status;
409 }
410
411 /**
412 * Implementation of local_credential_store_t.get_rsa_private_key.
413 */
414 static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this,
415 rsa_public_key_t *pubkey)
416 {
417 rsa_private_key_t *found = NULL, *current;
418
419 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
420
421 while (iterator->iterate(iterator, (void**)&current))
422 {
423 if (current->belongs_to(current, pubkey))
424 {
425 found = current->clone(current);
426 break;
427 }
428 }
429 iterator->destroy(iterator);
430 return found;
431 }
432
433 /**
434 * Implementation of local_credential_store_t.has_rsa_private_key.
435 */
436 static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
437 {
438 bool found = FALSE;
439 rsa_private_key_t *current;
440
441 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
442
443 while (iterator->iterate(iterator, (void**)&current))
444 {
445 if (current->belongs_to(current, pubkey))
446 {
447 found = TRUE;
448 break;
449 }
450 }
451 iterator->destroy(iterator);
452 return found;
453 }
454
455 /**
456 * Implementation of credential_store_t.get_auth_certificate.
457 */
458 static x509_t* get_auth_certificate(private_local_credential_store_t *this,
459 u_int auth_flags,
460 identification_t *id)
461 {
462 x509_t *found = NULL;
463 x509_t *current_cert;
464
465 iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
466
467 while (iterator->iterate(iterator, (void**)&current_cert))
468 {
469 if (current_cert->has_authority_flag(current_cert, auth_flags)
470 && id->equals(id, current_cert->get_subject(current_cert)))
471 {
472 found = current_cert;
473 break;
474 }
475 }
476 iterator->destroy(iterator);
477
478 return found;
479 }
480
481 /**
482 * Implementation of credential_store_t.get_ca_certificate_by_keyid.
483 */
484 static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *this,
485 chunk_t keyid)
486 {
487 x509_t *found = NULL;
488 x509_t *current_cert;
489
490 iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
491
492 while (iterator->iterate(iterator, (void**)&current_cert))
493 {
494 rsa_public_key_t *pubkey = current_cert->get_public_key(current_cert);
495
496 if (current_cert->has_authority_flag(current_cert, AUTH_CA)
497 && chunk_equals(keyid, pubkey->get_keyid(pubkey)))
498 {
499 found = current_cert;
500 break;
501 }
502 }
503 iterator->destroy(iterator);
504
505 return found;
506 }
507
508 /**
509 * Find an exact copy of a certificate in a linked list
510 */
511 static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
512 {
513 x509_t *found_cert = NULL, *current_cert;
514
515 iterator_t *iterator = certs->create_iterator(certs, TRUE);
516
517 while (iterator->iterate(iterator, (void**)&current_cert))
518 {
519 if (cert->equals(cert, current_cert))
520 {
521 found_cert = current_cert;
522 break;
523 }
524 }
525 iterator->destroy(iterator);
526
527 return found_cert;
528 }
529
530 /**
531 * Adds crl and ocsp uris to the corresponding issuer info record
532 */
533 static void add_uris(ca_info_t *issuer, x509_t *cert)
534 {
535 iterator_t *iterator;
536 identification_t *uri;
537
538 /* add any crl distribution points to the issuer ca info record */
539 iterator = cert->create_crluri_iterator(cert);
540
541 while (iterator->iterate(iterator, (void**)&uri))
542 {
543 issuer->add_crluri(issuer, uri->get_encoding(uri));
544 }
545 iterator->destroy(iterator);
546
547 /* add any ocsp access points to the issuer ca info record */
548 iterator = cert->create_ocspuri_iterator(cert);
549
550 while (iterator->iterate(iterator, (void**)&uri))
551 {
552 issuer->add_ocspuri(issuer, uri->get_encoding(uri));
553 }
554 iterator->destroy(iterator);
555 }
556
557 /**
558 * Implementation of credential_store_t.is_trusted
559 */
560 static bool is_trusted(private_local_credential_store_t *this, x509_t *cert)
561 {
562 int pathlen;
563 time_t until = UNDEFINED_TIME;
564 x509_t *cert_to_be_trusted = cert;
565
566 DBG2(DBG_CFG, "establishing trust in certificate:");
567
568 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
569 {
570 err_t ugh = NULL;
571 ca_info_t *issuer;
572 x509_t *issuer_cert;
573 rsa_public_key_t *issuer_public_key;
574 bool valid_signature;
575
576 DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
577 DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
578
579 ugh = cert->is_valid(cert, &until);
580 if (ugh != NULL)
581 {
582 DBG1(DBG_CFG, "certificate %s", ugh);
583 return FALSE;
584 }
585 DBG2(DBG_CFG, "certificate is valid");
586
587 issuer = get_issuer(this, cert);
588 if (issuer == NULL)
589 {
590 DBG1(DBG_CFG, "issuer not found");
591 return FALSE;
592 }
593 DBG2(DBG_CFG, "issuer found");
594
595 issuer_cert = issuer->get_certificate(issuer);
596 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
597 valid_signature = cert->verify(cert, issuer_public_key);
598
599 if (!valid_signature)
600 {
601 DBG1(DBG_CFG, "certificate signature is invalid");
602 return FALSE;
603 }
604 DBG2(DBG_CFG, "certificate signature is valid");
605
606 /* check if cert is a self-signed root ca */
607 if (pathlen > 0 && cert->is_self_signed(cert))
608 {
609 DBG2(DBG_CFG, "reached self-signed root ca");
610 cert_to_be_trusted->set_until(cert_to_be_trusted, until);
611 cert_to_be_trusted->set_status(cert_to_be_trusted, CERT_GOOD);
612 return TRUE;
613 }
614 else
615 {
616 /* go up one step in the trust chain */
617 cert = issuer_cert;
618 }
619 }
620 DBG1(DBG_CFG, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
621 return FALSE;
622 }
623
624 /**
625 * Implementation of credential_store_t.verify.
626 */
627 static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
628 {
629 int pathlen;
630 time_t until = UNDEFINED_TIME;
631
632 x509_t *end_cert = cert;
633 x509_t *cert_copy = find_certificate(this->certs, end_cert);
634
635 DBG2(DBG_CFG, "verifying end entity certificate:");
636
637 *found = (cert_copy != NULL);
638 if (*found)
639 {
640 DBG2(DBG_CFG,
641 "end entitity certificate is already in credential store");
642 }
643
644 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
645 {
646 err_t ugh = NULL;
647 ca_info_t *issuer;
648 x509_t *issuer_cert;
649 rsa_public_key_t *issuer_public_key;
650 bool valid_signature;
651
652 DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
653 DBG1(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
654
655 ugh = cert->is_valid(cert, &until);
656 if (ugh != NULL)
657 {
658 DBG1(DBG_CFG, "certificate %s", ugh);
659 return FALSE;
660 }
661 DBG2(DBG_CFG, "certificate is valid");
662
663 issuer = get_issuer(this, cert);
664 if (issuer == NULL)
665 {
666 DBG1(DBG_CFG, "issuer not found");
667 return FALSE;
668 }
669 DBG2(DBG_CFG, "issuer found");
670
671 issuer_cert = issuer->get_certificate(issuer);
672 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
673 valid_signature = cert->verify(cert, issuer_public_key);
674
675 if (!valid_signature)
676 {
677 DBG1(DBG_CFG, "certificate signature is invalid");
678 return FALSE;
679 }
680 DBG2(DBG_CFG, "certificate signature is valid");
681
682 /* check if cert is a self-signed root ca */
683 if (pathlen > 0 && cert->is_self_signed(cert))
684 {
685 DBG1(DBG_CFG, "reached self-signed root ca");
686
687 /* set the definite status and trust interval of the end entity certificate */
688 end_cert->set_until(end_cert, until);
689 if (cert_copy)
690 {
691 cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
692 cert_copy->set_until(cert_copy, until);
693 }
694 return TRUE;
695 }
696 else
697 {
698 bool strict;
699 time_t nextUpdate;
700 cert_status_t status;
701 certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
702
703 certinfo->set_nextUpdate(certinfo, until);
704
705 if (pathlen == 0)
706 {
707 /* add any crl and ocsp uris contained in the certificate under test */
708 add_uris(issuer, cert);
709 }
710
711 strict = issuer->is_strict(issuer);
712 DBG1(DBG_CFG, "issuer %s a strict crl policy",
713 strict ? "enforces":"does not enforce");
714
715 /* first check certificate revocation using ocsp */
716 status = issuer->verify_by_ocsp(issuer, certinfo, &this->public.credential_store);
717
718 /* if ocsp service is not available then fall back to crl */
719 if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && strict))
720 {
721 status = issuer->verify_by_crl(issuer, certinfo, CRL_DIR);
722 }
723
724 nextUpdate = certinfo->get_nextUpdate(certinfo);
725 cert->set_status(cert, status);
726
727 switch (status)
728 {
729 case CERT_GOOD:
730 /* set nextUpdate */
731 cert->set_until(cert, nextUpdate);
732
733 /* if status information is stale */
734 if (strict && nextUpdate < time(NULL))
735 {
736 DBG2(DBG_CFG, "certificate is good but status is stale");
737 certinfo->destroy(certinfo);
738 return FALSE;
739 }
740 DBG1(DBG_CFG, "certificate is good");
741
742 /* with strict crl policy the public key must have the same
743 * lifetime as the validity of the ocsp status or crl lifetime
744 */
745 if (strict && nextUpdate < until)
746 until = nextUpdate;
747 break;
748 case CERT_REVOKED:
749 {
750 time_t revocationTime = certinfo->get_revocationTime(certinfo);
751 DBG1(DBG_CFG,
752 "certificate was revoked on %T, reason: %N",
753 &revocationTime, crl_reason_names,
754 certinfo->get_revocationReason(certinfo));
755
756 /* set revocationTime */
757 cert->set_until(cert, revocationTime);
758
759 /* update status of end certificate in the credential store */
760 if (cert_copy)
761 {
762 if (pathlen > 0)
763 {
764 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
765 }
766 else
767 {
768 cert_copy->set_status(cert_copy, CERT_REVOKED);
769 cert_copy->set_until(cert_copy,
770 certinfo->get_revocationTime(certinfo));
771 }
772 }
773 certinfo->destroy(certinfo);
774 return FALSE;
775 }
776 case CERT_UNKNOWN:
777 case CERT_UNDEFINED:
778 default:
779 DBG1(DBG_CFG, "certificate status unknown");
780 if (strict)
781 {
782 /* update status of end certificate in the credential store */
783 if (cert_copy)
784 {
785 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
786 }
787 certinfo->destroy(certinfo);
788 return FALSE;
789 }
790 break;
791 }
792 certinfo->destroy(certinfo);
793 }
794 /* go up one step in the trust chain */
795 cert = issuer_cert;
796 }
797 DBG1(DBG_CFG, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
798 return FALSE;
799 }
800
801 /**
802 * Add a unique certificate to a linked list
803 */
804 static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
805 {
806 x509_t *found_cert = find_certificate(certs, cert);
807
808 if (found_cert)
809 {
810 /* add the authority flags */
811 found_cert->add_authority_flags(found_cert, cert->get_authority_flags(cert));
812
813 cert->destroy(cert);
814 return found_cert;
815 }
816 else
817 {
818 certs->insert_last(certs, (void*)cert);
819 return cert;
820 }
821 }
822
823 /**
824 * Add a unique ca info record to a linked list
825 */
826 static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
827 {
828 ca_info_t *current_ca_info;
829 ca_info_t *found_ca_info = NULL;
830
831 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
832
833 while (iterator->iterate(iterator, (void**)&current_ca_info))
834 {
835 if (current_ca_info->equals(current_ca_info, ca_info))
836 {
837 found_ca_info = current_ca_info;
838 break;
839 }
840 }
841 iterator->destroy(iterator);
842
843 if (found_ca_info)
844 {
845 current_ca_info->add_info(current_ca_info, ca_info);
846 ca_info->destroy(ca_info);
847 }
848 else
849 {
850 this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
851 }
852 }
853
854 /**
855 * Release ca info record of a given name
856 */
857 static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
858 {
859 status_t status = NOT_FOUND;
860 ca_info_t *ca_info;
861
862 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
863
864 while (iterator->iterate(iterator, (void**)&ca_info))
865 {
866 if (ca_info->equals_name_release_info(ca_info, name))
867 {
868 status = SUCCESS;
869 break;
870 }
871 }
872 iterator->destroy(iterator);
873
874 return status;
875 }
876
877 /**
878 * Implements local_credential_store_t.add_end_certificate
879 */
880 static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
881 {
882 x509_t *ret_cert = add_certificate(this->certs, cert);
883
884 /* add crl and ocsp uris the first time the certificate is added */
885 if (ret_cert == cert)
886 {
887 ca_info_t *issuer = get_issuer(this, cert);
888
889 if (issuer)
890 {
891 add_uris(issuer, cert);
892 }
893 }
894 return ret_cert;
895 }
896
897 /**
898 * Implements local_credential_store_t.add_auth_certificate
899 */
900 static x509_t* add_auth_certificate(private_local_credential_store_t *this, x509_t *cert, u_int auth_flags)
901 {
902 cert->add_authority_flags(cert, auth_flags);
903 return add_certificate(this->auth_certs, cert);
904 }
905
906 /**
907 * Implements local_credential_store_t.create_cert_iterator
908 */
909 static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
910 {
911 return this->certs->create_iterator(this->certs, TRUE);
912 }
913
914 /**
915 * Implements local_credential_store_t.create_cacert_iterator
916 */
917 static iterator_t* create_auth_cert_iterator(private_local_credential_store_t *this)
918 {
919 return this->auth_certs->create_iterator(this->auth_certs, TRUE);
920 }
921
922 /**
923 * Implements local_credential_store_t.create_cainfo_iterator
924 */
925 static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
926 {
927 return this->ca_infos->create_iterator(this->ca_infos, TRUE);
928 }
929
930 /**
931 * Implements local_credential_store_t.load_auth_certificates
932 */
933 static void load_auth_certificates(private_local_credential_store_t *this,
934 u_int auth_flag,
935 const char* label,
936 const char* path)
937 {
938 struct dirent* entry;
939 struct stat stb;
940 DIR* dir;
941
942 DBG1(DBG_CFG, "loading %s certificates from '%s'", label, path);
943
944 dir = opendir(path);
945 if (dir == NULL)
946 {
947 DBG1(DBG_CFG, "error opening %s certs directory '%s'", label, path);
948 return;
949 }
950
951 while ((entry = readdir(dir)) != NULL)
952 {
953 char file[PATH_BUF];
954
955 snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
956
957 if (stat(file, &stb) == -1)
958 {
959 continue;
960 }
961 /* try to parse all regular files */
962 if (stb.st_mode & S_IFREG)
963 {
964 x509_t *cert = x509_create_from_file(file, label);
965
966 if (cert)
967 {
968 err_t ugh = cert->is_valid(cert, NULL);
969
970 if (ugh != NULL)
971 {
972 DBG1(DBG_CFG, "warning: %s certificate %s", label, ugh);
973 }
974
975 if (auth_flag == AUTH_CA && !cert->is_ca(cert))
976 {
977 DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
978 cert->destroy(cert);
979 }
980 else
981 {
982 x509_t *ret_cert;
983
984 cert->add_authority_flags(cert, auth_flag);
985
986 ret_cert = add_certificate(this->auth_certs, cert);
987
988 if (auth_flag == AUTH_CA && ret_cert == cert)
989 {
990 ca_info_t *ca_info = ca_info_create(NULL, cert);
991
992 add_ca_info(this, ca_info);
993 }
994 }
995 }
996 }
997 }
998 closedir(dir);
999 }
1000
1001 /**
1002 * Implements local_credential_store_t.load_ca_certificates
1003 */
1004 static void load_ca_certificates(private_local_credential_store_t *this)
1005 {
1006 load_auth_certificates(this, AUTH_CA, "ca", CA_CERTIFICATE_DIR);
1007
1008 /* add any crl and ocsp uris found in the ca certificates to the
1009 * corresponding issuer info record. We can do this only after all
1010 * ca certificates have been loaded and the ca hierarchy is known.
1011 */
1012 {
1013 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
1014 ca_info_t *ca_info;
1015
1016 while (iterator->iterate(iterator, (void **)&ca_info))
1017 {
1018 x509_t *cacert = ca_info->get_certificate(ca_info);
1019 ca_info_t *issuer = get_issuer(this, cacert);
1020
1021 if (issuer)
1022 {
1023 add_uris(issuer, cacert);
1024 }
1025 }
1026 iterator->destroy(iterator);
1027 }
1028 }
1029
1030 /**
1031 * Implements local_credential_store_t.load_aa_certificates
1032 */
1033 static void load_aa_certificates(private_local_credential_store_t *this)
1034 {
1035 load_auth_certificates(this, AUTH_AA, "aa", AA_CERTIFICATE_DIR);
1036 }
1037
1038 /**
1039 * Add a unique attribute certificate to a linked list
1040 */
1041 static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert)
1042 {
1043 /* TODO add a new attribute certificate to the linked list */
1044 }
1045
1046 /**
1047 * Implements local_credential_store_t.load_attr_certificates
1048 */
1049 static void load_attr_certificates(private_local_credential_store_t *this)
1050 {
1051 struct dirent* entry;
1052 struct stat stb;
1053 DIR* dir;
1054
1055 const char *path = ATTR_CERTIFICATE_DIR;
1056
1057 DBG1(DBG_CFG, "loading attribute certificates from '%s'", path);
1058
1059 dir = opendir(ATTR_CERTIFICATE_DIR);
1060 if (dir == NULL)
1061 {
1062 DBG1(DBG_CFG, "error opening attribute certs directory '%s'", path);
1063 return;
1064 }
1065
1066 while ((entry = readdir(dir)) != NULL)
1067 {
1068 char file[PATH_BUF];
1069
1070 snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
1071
1072 if (stat(file, &stb) == -1)
1073 {
1074 continue;
1075 }
1076 /* try to parse all regular files */
1077 if (stb.st_mode & S_IFREG)
1078 {
1079 x509ac_t *cert = x509ac_create_from_file(file);
1080
1081 if (cert)
1082 {
1083 err_t ugh = cert->is_valid(cert, NULL);
1084
1085 if (ugh != NULL)
1086 {
1087 DBG1(DBG_CFG, "warning: attribute certificate %s", ugh);
1088 }
1089 add_attr_certificate(this, cert);
1090 }
1091 }
1092 }
1093 closedir(dir);
1094
1095
1096 }
1097
1098 /**
1099 * Implements local_credential_store_t.load_ocsp_certificates
1100 */
1101 static void load_ocsp_certificates(private_local_credential_store_t *this)
1102 {
1103 load_auth_certificates(this, AUTH_OCSP, "ocsp", OCSP_CERTIFICATE_DIR);
1104 }
1105
1106 /**
1107 * Add the latest crl to the issuing ca
1108 */
1109 static void add_crl(private_local_credential_store_t *this, crl_t *crl, const char *path)
1110 {
1111 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
1112 ca_info_t *ca_info;
1113 bool found = FALSE;
1114
1115 while (iterator->iterate(iterator, (void**)&ca_info))
1116 {
1117 if (ca_info->is_crl_issuer(ca_info, crl))
1118 {
1119 char buffer[BUF_LEN];
1120 chunk_t uri = { buffer, 7 + strlen(path) };
1121
1122 ca_info->add_crl(ca_info, crl);
1123 if (uri.len < BUF_LEN)
1124 {
1125 snprintf(buffer, BUF_LEN, "file://%s", path);
1126 ca_info->add_crluri(ca_info, uri);
1127 }
1128 found = TRUE;
1129 break;
1130 }
1131 }
1132 iterator->destroy(iterator);
1133
1134 if (!found)
1135 {
1136 crl->destroy(crl);
1137 DBG2(DBG_CFG, " no issuing ca found for this crl - discarded");
1138 }
1139 }
1140
1141 /**
1142 * Implements local_credential_store_t.load_crls
1143 */
1144 static void load_crls(private_local_credential_store_t *this)
1145 {
1146 struct dirent* entry;
1147 struct stat stb;
1148 DIR* dir;
1149 crl_t *crl;
1150
1151 DBG1(DBG_CFG, "loading crls from '%s'", CRL_DIR);
1152
1153 dir = opendir(CRL_DIR);
1154 if (dir == NULL)
1155 {
1156 DBG1(DBG_CFG, "error opening crl directory '%s'", CRL_DIR);
1157 return;
1158 }
1159
1160 while ((entry = readdir(dir)) != NULL)
1161 {
1162 char file[PATH_BUF];
1163
1164 snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
1165
1166 if (stat(file, &stb) == -1)
1167 {
1168 continue;
1169 }
1170 /* try to parse all regular files */
1171 if (stb.st_mode & S_IFREG)
1172 {
1173 crl = crl_create_from_file(file);
1174 if (crl)
1175 {
1176 DBG1(DBG_CFG, " crl is %s", crl->is_valid(crl)? "valid":"stale");
1177 add_crl(this, crl, file);
1178 }
1179 }
1180 }
1181 closedir(dir);
1182 }
1183
1184 /**
1185 * Convert a string of characters into a binary secret
1186 * A string between single or double quotes is treated as ASCII characters
1187 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
1188 */
1189 static err_t extract_secret(chunk_t *secret, chunk_t *line)
1190 {
1191 chunk_t raw_secret;
1192 char delimiter = ' ';
1193 bool quotes = FALSE;
1194
1195 if (!eat_whitespace(line))
1196 {
1197 return "missing secret";
1198 }
1199
1200 if (*line->ptr == '\'' || *line->ptr == '"')
1201 {
1202 quotes = TRUE;
1203 delimiter = *line->ptr;
1204 line->ptr++; line->len--;
1205 }
1206
1207 if (!extract_token(&raw_secret, delimiter, line))
1208 {
1209 if (delimiter == ' ')
1210 {
1211 raw_secret = *line;
1212 }
1213 else
1214 {
1215 return "missing second delimiter";
1216 }
1217 }
1218
1219 if (quotes)
1220 { /* treat as an ASCII string */
1221 if (raw_secret.len > secret->len)
1222 return "secret larger than buffer";
1223 memcpy(secret->ptr, raw_secret.ptr, raw_secret.len);
1224 secret->len = raw_secret.len;
1225 }
1226 else
1227 { /* convert from HEX or Base64 to binary */
1228 size_t len;
1229 err_t ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
1230
1231 if (ugh != NULL)
1232 return ugh;
1233 if (len > secret->len)
1234 return "secret larger than buffer";
1235 secret->len = len;
1236 }
1237 return NULL;
1238 }
1239
1240 /**
1241 * Implements local_credential_store_t.load_secrets
1242 */
1243 static void load_secrets(private_local_credential_store_t *this)
1244 {
1245 FILE *fd = fopen(SECRETS_FILE, "r");
1246
1247 if (fd)
1248 {
1249 int bytes;
1250 int line_nr = 0;
1251 chunk_t chunk, src, line;
1252
1253 DBG1(DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE);
1254
1255 fseek(fd, 0, SEEK_END);
1256 chunk.len = ftell(fd);
1257 rewind(fd);
1258 chunk.ptr = malloc(chunk.len);
1259 bytes = fread(chunk.ptr, 1, chunk.len, fd);
1260 fclose(fd);
1261
1262 src = chunk;
1263
1264 while (fetchline(&src, &line))
1265 {
1266 chunk_t ids, token;
1267 bool is_eap = FALSE;
1268
1269 line_nr++;
1270
1271 if (!eat_whitespace(&line))
1272 {
1273 continue;
1274 }
1275 if (!extract_token(&ids, ':', &line))
1276 {
1277 DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
1278 goto error;
1279 }
1280 /* NULL terminate the ids string by replacing the : separator */
1281 *(ids.ptr + ids.len) = '\0';
1282
1283 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
1284 {
1285 DBG1(DBG_CFG, "line %d: missing token", line_nr);
1286 goto error;
1287 }
1288 if (match("RSA", &token))
1289 {
1290 char path[PATH_BUF];
1291 chunk_t filename;
1292
1293 char buf[BUF_LEN];
1294 chunk_t secret = { buf, BUF_LEN };
1295 chunk_t *passphrase = NULL;
1296
1297 rsa_private_key_t *key;
1298
1299 err_t ugh = extract_value(&filename, &line);
1300
1301 if (ugh != NULL)
1302 {
1303 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1304 goto error;
1305 }
1306 if (filename.len == 0)
1307 {
1308 DBG1(DBG_CFG, "line %d: empty filename", line_nr);
1309 goto error;
1310 }
1311 if (*filename.ptr == '/')
1312 {
1313 /* absolute path name */
1314 snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
1315 }
1316 else
1317 {
1318 /* relative path name */
1319 snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
1320 filename.len, filename.ptr);
1321 }
1322
1323 /* check for optional passphrase */
1324 if (eat_whitespace(&line))
1325 {
1326 ugh = extract_secret(&secret, &line);
1327 if (ugh != NULL)
1328 {
1329 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
1330 goto error;
1331 }
1332 if (secret.len > 0)
1333 passphrase = &secret;
1334 }
1335 key = rsa_private_key_create_from_file(path, passphrase);
1336 if (key)
1337 {
1338 this->private_keys->insert_last(this->private_keys, (void*)key);
1339 }
1340 }
1341 else if ( match("PSK", &token) ||
1342 ((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE)))
1343 {
1344 shared_key_t *shared_key;
1345
1346 char buf[BUF_LEN];
1347 chunk_t secret = { buf, BUF_LEN };
1348
1349 err_t ugh = extract_secret(&secret, &line);
1350 if (ugh != NULL)
1351 {
1352 DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
1353 goto error;
1354 }
1355
1356 DBG1(DBG_CFG, " loading %s key for %s",
1357 is_eap ? "EAP" : "shared",
1358 ids.len > 0 ? (char*)ids.ptr : "%any");
1359
1360 DBG4(DBG_CFG, " secret:", secret);
1361
1362 shared_key = shared_key_create(secret);
1363 if (shared_key)
1364 {
1365 if (is_eap)
1366 {
1367 this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
1368 }
1369 else
1370 {
1371 this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
1372 }
1373 }
1374 while (ids.len > 0)
1375 {
1376 chunk_t id;
1377 identification_t *peer_id;
1378
1379 ugh = extract_value(&id, &ids);
1380 if (ugh != NULL)
1381 {
1382 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1383 goto error;
1384 }
1385 if (id.len == 0)
1386 {
1387 continue;
1388 }
1389
1390 /* NULL terminate the ID string */
1391 *(id.ptr + id.len) = '\0';
1392
1393 peer_id = identification_create_from_string(id.ptr);
1394 if (peer_id == NULL)
1395 {
1396 DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
1397 goto error;
1398 }
1399
1400 if (peer_id->get_type(peer_id) == ID_ANY)
1401 {
1402 peer_id->destroy(peer_id);
1403 continue;
1404 }
1405 shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
1406 }
1407 }
1408 else if (match("PIN", &token))
1409 {
1410
1411 }
1412 else
1413 {
1414 DBG1(DBG_CFG, "line %d: token must be either "
1415 "RSA, PSK, EAP, or PIN", line_nr, token.len);
1416 goto error;
1417 }
1418 }
1419 error:
1420 free(chunk.ptr);
1421 }
1422 else
1423 {
1424 DBG1(DBG_CFG, "could not open file '%s': %s", SECRETS_FILE,
1425 strerror(errno));
1426 }
1427 }
1428
1429 /**
1430 * Implementation of local_credential_store_t.destroy.
1431 */
1432 static void destroy(private_local_credential_store_t *this)
1433 {
1434 this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
1435 this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
1436 this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
1437 this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
1438 this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
1439 this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
1440 free(this);
1441 }
1442
1443 /**
1444 * Described in header.
1445 */
1446 local_credential_store_t * local_credential_store_create(void)
1447 {
1448 private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
1449
1450 this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
1451 this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
1452 this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
1453 this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
1454 this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
1455 this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
1456 this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
1457 this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
1458 this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,const x509_t*))get_issuer;
1459 this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,x509_t*))is_trusted;
1460 this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
1461 this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
1462 this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
1463 this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;
1464 this->public.credential_store.add_ca_info = (void (*) (credential_store_t*,ca_info_t*))add_ca_info;
1465 this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
1466 this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
1467 this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
1468 this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
1469 this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
1470 this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates;
1471 this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates;
1472 this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
1473 this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
1474 this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets;
1475 this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
1476
1477 /* private variables */
1478 this->shared_keys = linked_list_create();
1479 this->eap_keys = linked_list_create();
1480 this->private_keys = linked_list_create();
1481 this->certs = linked_list_create();
1482 this->auth_certs = linked_list_create();
1483 this->ca_infos = linked_list_create();
1484
1485 return (&this->public);
1486 }