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