Return to mem_cred.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / credentials / sets |
1.1 misho 1: /*
2: * Copyright (C) 2010-2016 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (C) 2010 Martin Willi
6: * Copyright (C) 2010 revosec AG
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include "mem_cred.h"
20:
21: #include <threading/rwlock.h>
22: #include <collections/linked_list.h>
23:
24: typedef struct private_mem_cred_t private_mem_cred_t;
25:
26: /**
27: * Private data of an mem_cred_t object.
28: */
29: struct private_mem_cred_t {
30:
31: /**
32: * Public mem_cred_t interface.
33: */
34: mem_cred_t public;
35:
36: /**
37: * Lock for this set
38: */
39: rwlock_t *lock;
40:
41: /**
42: * List of trusted certificates, certificate_t
43: */
44: linked_list_t *trusted;
45:
46: /**
47: * List of trusted and untrusted certificates, certificate_t
48: */
49: linked_list_t *untrusted;
50:
51: /**
52: * List of private keys, private_key_t
53: */
54: linked_list_t *keys;
55:
56: /**
57: * List of shared keys, as shared_entry_t
58: */
59: linked_list_t *shared;
60:
61: /**
62: * List of CDPs, as cdp_t
63: */
64: linked_list_t *cdps;
65: };
66:
67: /**
68: * Data for the certificate enumerator
69: */
70: typedef struct {
71: rwlock_t *lock;
72: certificate_type_t cert;
73: key_type_t key;
74: identification_t *id;
75: } cert_data_t;
76:
77: CALLBACK(cert_data_destroy, void,
78: cert_data_t *data)
79: {
80: data->lock->unlock(data->lock);
81: free(data);
82: }
83:
84: CALLBACK(certs_filter, bool,
85: cert_data_t *data, enumerator_t *orig, va_list args)
86: {
87: certificate_t *cert, **out;
88:
89: VA_ARGS_VGET(args, out);
90:
91: while (orig->enumerate(orig, &cert))
92: {
1.1.1.2 ! misho 93: if (certificate_matches(cert, data->cert, data->key, data->id))
1.1 misho 94: {
95: *out = cert;
96: return TRUE;
97: }
98: }
99: return FALSE;
100: }
101:
102: METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
103: private_mem_cred_t *this, certificate_type_t cert, key_type_t key,
104: identification_t *id, bool trusted)
105: {
106: cert_data_t *data;
107: enumerator_t *enumerator;
108:
109: INIT(data,
110: .lock = this->lock,
111: .cert = cert,
112: .key = key,
113: .id = id,
114: );
115: this->lock->read_lock(this->lock);
116: if (trusted)
117: {
118: enumerator = this->trusted->create_enumerator(this->trusted);
119: }
120: else
121: {
122: enumerator = this->untrusted->create_enumerator(this->untrusted);
123: }
124: return enumerator_create_filter(enumerator, certs_filter, data,
125: cert_data_destroy);
126: }
127:
128: CALLBACK(certificate_equals, bool,
129: certificate_t *item, va_list args)
130: {
131: certificate_t *cert;
132:
133: VA_ARGS_VGET(args, cert);
134: return item->equals(item, cert);
135: }
136:
137: /**
138: * Add a certificate the the cache. Returns a reference to "cert" or a
139: * previously cached certificate that equals "cert".
140: */
141: static certificate_t *add_cert_internal(private_mem_cred_t *this, bool trusted,
142: certificate_t *cert)
143: {
144: certificate_t *cached;
145: this->lock->write_lock(this->lock);
146: if (this->untrusted->find_first(this->untrusted, certificate_equals,
147: (void**)&cached, cert))
148: {
149: cert->destroy(cert);
150: cert = cached->get_ref(cached);
151: }
152: else
153: {
154: if (trusted)
155: {
156: this->trusted->insert_first(this->trusted, cert->get_ref(cert));
157: }
158: this->untrusted->insert_first(this->untrusted, cert->get_ref(cert));
159: }
160: this->lock->unlock(this->lock);
161: return cert;
162: }
163:
164: METHOD(mem_cred_t, add_cert, void,
165: private_mem_cred_t *this, bool trusted, certificate_t *cert)
166: {
167: certificate_t *cached = add_cert_internal(this, trusted, cert);
168: cached->destroy(cached);
169: }
170:
171: METHOD(mem_cred_t, add_cert_ref, certificate_t*,
172: private_mem_cred_t *this, bool trusted, certificate_t *cert)
173: {
174: return add_cert_internal(this, trusted, cert);
175: }
176:
177: METHOD(mem_cred_t, get_cert_ref, certificate_t*,
178: private_mem_cred_t *this, certificate_t *cert)
179: {
180: certificate_t *cached;
181:
182: this->lock->read_lock(this->lock);
183: if (this->untrusted->find_first(this->untrusted, certificate_equals,
184: (void**)&cached, cert))
185: {
186: cert->destroy(cert);
187: cert = cached->get_ref(cached);
188: }
189: this->lock->unlock(this->lock);
190:
191: return cert;
192: }
193:
194: METHOD(mem_cred_t, add_crl, bool,
195: private_mem_cred_t *this, crl_t *crl)
196: {
197: certificate_t *current, *cert = &crl->certificate;
198: enumerator_t *enumerator;
199: bool new = TRUE;
200:
201: this->lock->write_lock(this->lock);
202: enumerator = this->untrusted->create_enumerator(this->untrusted);
203: while (enumerator->enumerate(enumerator, (void**)¤t))
204: {
205: if (current->get_type(current) == CERT_X509_CRL)
206: {
207: chunk_t base;
208: bool found = FALSE;
209: crl_t *crl_c = (crl_t*)current;
210: chunk_t authkey = crl->get_authKeyIdentifier(crl);
211: chunk_t authkey_c = crl_c->get_authKeyIdentifier(crl_c);
212:
213: /* compare authorityKeyIdentifiers if available */
214: if (chunk_equals(authkey, authkey_c))
215: {
216: found = TRUE;
217: }
218: else
219: {
220: identification_t *issuer = cert->get_issuer(cert);
221: identification_t *issuer_c = current->get_issuer(current);
222:
223: /* otherwise compare issuer distinguished names */
224: if (issuer->equals(issuer, issuer_c))
225: {
226: found = TRUE;
227: }
228: }
229: if (found)
230: {
231: /* we keep at most one delta CRL for each base CRL */
232: if (crl->is_delta_crl(crl, &base))
233: {
234: if (!crl_c->is_delta_crl(crl_c, NULL))
235: {
236: if (chunk_equals(base, crl_c->get_serial(crl_c)))
237: { /* keep the added delta and the existing base CRL
238: * but check if this is the newest delta CRL for
239: * the same base */
240: continue;
241: }
242: }
243: }
244: else if (crl_c->is_delta_crl(crl_c, &base))
245: {
246: if (chunk_equals(base, crl->get_serial(crl)))
247: { /* keep the existing delta and the added base CRL,
248: * but check if we don't store it already */
249: continue;
250: }
251: }
252: new = crl_is_newer(crl, crl_c);
253: if (!new)
254: {
255: cert->destroy(cert);
256: break;
257: }
258: /* we remove the existing older CRL but there might be other
259: * delta or base CRLs we can replace */
260: this->untrusted->remove_at(this->untrusted, enumerator);
261: current->destroy(current);
262: }
263: }
264: }
265: enumerator->destroy(enumerator);
266:
267: if (new)
268: {
269: this->untrusted->insert_first(this->untrusted, cert);
270: }
271: this->lock->unlock(this->lock);
272: return new;
273: }
274:
275: /**
276: * Data for key enumerator
277: */
278: typedef struct {
279: rwlock_t *lock;
280: key_type_t type;
281: identification_t *id;
282: } key_data_t;
283:
284: CALLBACK(key_data_destroy, void,
285: key_data_t *data)
286: {
287: data->lock->unlock(data->lock);
288: free(data);
289: }
290:
291: CALLBACK(key_filter, bool,
292: key_data_t *data, enumerator_t *orig, va_list args)
293: {
294: private_key_t *key, **out;
295:
296: VA_ARGS_VGET(args, out);
297:
298: while (orig->enumerate(orig, &key))
299: {
300: if (data->type == KEY_ANY || data->type == key->get_type(key))
301: {
302: if (data->id == NULL ||
303: key->has_fingerprint(key, data->id->get_encoding(data->id)))
304: {
305: *out = key;
306: return TRUE;
307: }
308: }
309: }
310: return FALSE;
311: }
312:
313: METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
314: private_mem_cred_t *this, key_type_t type, identification_t *id)
315: {
316: key_data_t *data;
317:
318: INIT(data,
319: .lock = this->lock,
320: .type = type,
321: .id = id,
322: );
323: this->lock->read_lock(this->lock);
324: return enumerator_create_filter(this->keys->create_enumerator(this->keys),
325: key_filter, data, key_data_destroy);
326: }
327:
328: METHOD(mem_cred_t, add_key, void,
329: private_mem_cred_t *this, private_key_t *key)
330: {
331: enumerator_t *enumerator;
332: private_key_t *current;
333:
334: this->lock->write_lock(this->lock);
335:
336: enumerator = this->keys->create_enumerator(this->keys);
337: while (enumerator->enumerate(enumerator, ¤t))
338: {
339: if (current->equals(current, key))
340: {
341: this->keys->remove_at(this->keys, enumerator);
342: current->destroy(current);
343: break;
344: }
345: }
346: enumerator->destroy(enumerator);
347:
348: this->keys->insert_first(this->keys, key);
349:
350: this->lock->unlock(this->lock);
351: }
352:
353: METHOD(mem_cred_t, remove_key, bool,
354: private_mem_cred_t *this, chunk_t fp)
355: {
356: enumerator_t *enumerator;
357: private_key_t *current;
358: bool found = FALSE;
359:
360: this->lock->write_lock(this->lock);
361:
362: enumerator = this->keys->create_enumerator(this->keys);
363: while (enumerator->enumerate(enumerator, ¤t))
364: {
365: if (current->has_fingerprint(current, fp))
366: {
367: this->keys->remove_at(this->keys, enumerator);
368: current->destroy(current);
369: found = TRUE;
370: break;
371: }
372: }
373: enumerator->destroy(enumerator);
374:
375: this->lock->unlock(this->lock);
376: return found;
377: }
378:
379: /**
380: * Shared key entry
381: */
382: typedef struct {
383: /** shared key */
384: shared_key_t *shared;
385: /** list of owners, identification_t */
386: linked_list_t *owners;
387: /** optional unique identifier */
388: char *id;
389: } shared_entry_t;
390:
391: /**
392: * Clean up a shared entry
393: */
394: static void shared_entry_destroy(shared_entry_t *entry)
395: {
396: entry->owners->destroy_offset(entry->owners,
397: offsetof(identification_t, destroy));
398: entry->shared->destroy(entry->shared);
399: free(entry->id);
400: free(entry);
401: }
402:
403: /**
404: * Check if two shared key entries are equal (ignoring the unique identifier)
405: */
406: static bool shared_entry_equals(shared_entry_t *a, shared_entry_t *b)
407: {
408: enumerator_t *e1, *e2;
409: identification_t *id1, *id2;
410: bool equals = TRUE;
411:
412: if (a->shared->get_type(a->shared) != b->shared->get_type(b->shared))
413: {
414: return FALSE;
415: }
416: if (!chunk_equals(a->shared->get_key(a->shared),
417: b->shared->get_key(b->shared)))
418: {
419: return FALSE;
420: }
421: if (a->owners->get_count(a->owners) != b->owners->get_count(b->owners))
422: {
423: return FALSE;
424: }
425: e1 = a->owners->create_enumerator(a->owners);
426: e2 = b->owners->create_enumerator(b->owners);
427: while (e1->enumerate(e1, &id1) && e2->enumerate(e2, &id2))
428: {
429: if (!id1->equals(id1, id2))
430: {
431: equals = FALSE;
432: break;
433: }
434: }
435: e1->destroy(e1);
436: e2->destroy(e2);
437:
438: return equals;
439: }
440:
441: /**
442: * Data for the shared_key enumerator
443: */
444: typedef struct {
445: rwlock_t *lock;
446: identification_t *me;
447: identification_t *other;
448: shared_key_type_t type;
449: } shared_data_t;
450:
451: CALLBACK(shared_data_destroy, void,
452: shared_data_t *data)
453: {
454: data->lock->unlock(data->lock);
455: free(data);
456: }
457:
458: /**
459: * Get the best match of an owner in an entry.
460: */
461: static id_match_t has_owner(shared_entry_t *entry, identification_t *owner)
462: {
463: enumerator_t *enumerator;
464: id_match_t match, best = ID_MATCH_NONE;
465: identification_t *current;
466:
467: enumerator = entry->owners->create_enumerator(entry->owners);
468: while (enumerator->enumerate(enumerator, ¤t))
469: {
470: match = owner->matches(owner, current);
471: if (match > best)
472: {
473: best = match;
474: }
475: }
476: enumerator->destroy(enumerator);
477: return best;
478: }
479:
480: CALLBACK(shared_filter, bool,
481: shared_data_t *data, enumerator_t *orig, va_list args)
482: {
483: id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE;
484: shared_entry_t *entry;
485: shared_key_t **out;
486: id_match_t *me, *other;
487:
488: VA_ARGS_VGET(args, out, me, other);
489:
490: while (orig->enumerate(orig, &entry))
491: {
492: if (data->type != SHARED_ANY &&
493: entry->shared->get_type(entry->shared) != data->type)
494: {
495: continue;
496: }
497: if (data->me)
498: {
499: my_match = has_owner(entry, data->me);
500: }
501: if (data->other)
502: {
503: other_match = has_owner(entry, data->other);
504: }
505: if ((data->me || data->other) && (!my_match && !other_match))
506: {
507: continue;
508: }
509: *out = entry->shared;
510: if (me)
511: {
512: *me = my_match;
513: }
514: if (other)
515: {
516: *other = other_match;
517: }
518: return TRUE;
519: }
520: return FALSE;
521: }
522:
523: METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
524: private_mem_cred_t *this, shared_key_type_t type,
525: identification_t *me, identification_t *other)
526: {
527: shared_data_t *data;
528:
529: INIT(data,
530: .lock = this->lock,
531: .me = me,
532: .other = other,
533: .type = type,
534: );
535: data->lock->read_lock(data->lock);
536: return enumerator_create_filter(
537: this->shared->create_enumerator(this->shared),
538: shared_filter, data, shared_data_destroy);
539: }
540:
541: METHOD(mem_cred_t, add_shared_unique, void,
542: private_mem_cred_t *this, char *id, shared_key_t *shared,
543: linked_list_t* owners)
544: {
545: shared_entry_t *current, *new;
546: enumerator_t *enumerator;
547:
548: INIT(new,
549: .shared = shared,
550: .owners = owners,
551: .id = strdupnull(id),
552: );
553:
554: this->lock->write_lock(this->lock);
555:
556: enumerator = this->shared->create_enumerator(this->shared);
557: while (enumerator->enumerate(enumerator, ¤t))
558: {
559: /* always replace keys with the same unique identifier, only compare
560: * them if both have no unique id assigned */
561: if ((id && streq(id, current->id)) ||
562: (!id && !current->id && shared_entry_equals(current, new)))
563: {
564: this->shared->remove_at(this->shared, enumerator);
565: shared_entry_destroy(current);
566: break;
567: }
568: }
569: enumerator->destroy(enumerator);
570:
571: this->shared->insert_first(this->shared, new);
572:
573: this->lock->unlock(this->lock);
574: }
575:
576: METHOD(mem_cred_t, add_shared_list, void,
577: private_mem_cred_t *this, shared_key_t *shared, linked_list_t* owners)
578: {
579: add_shared_unique(this, NULL, shared, owners);
580: }
581:
582: METHOD(mem_cred_t, add_shared, void,
583: private_mem_cred_t *this, shared_key_t *shared, ...)
584: {
585: identification_t *id;
586: linked_list_t *owners = linked_list_create();
587: va_list args;
588:
589: va_start(args, shared);
590: do
591: {
592: id = va_arg(args, identification_t*);
593: if (id)
594: {
595: owners->insert_first(owners, id);
596: }
597: }
598: while (id);
599: va_end(args);
600:
601: add_shared_list(this, shared, owners);
602: }
603:
604: METHOD(mem_cred_t, remove_shared_unique, void,
605: private_mem_cred_t *this, char *id)
606: {
607: enumerator_t *enumerator;
608: shared_entry_t *current;
609:
610: if (!id)
611: {
612: return;
613: }
614:
615: this->lock->write_lock(this->lock);
616:
617: enumerator = this->shared->create_enumerator(this->shared);
618: while (enumerator->enumerate(enumerator, ¤t))
619: {
620: if (streq(id, current->id))
621: {
622: this->shared->remove_at(this->shared, enumerator);
623: shared_entry_destroy(current);
624: break;
625: }
626: }
627: enumerator->destroy(enumerator);
628:
629: this->lock->unlock(this->lock);
630: }
631:
632: CALLBACK(unique_filter, bool,
633: void *unused, enumerator_t *orig, va_list args)
634: {
635: shared_entry_t *entry;
636: char **id;
637:
638: VA_ARGS_VGET(args, id);
639:
640: while (orig->enumerate(orig, &entry))
641: {
642: if (!entry->id)
643: {
644: continue;
645: }
646: if (id)
647: {
648: *id = entry->id;
649: }
650: return TRUE;
651: }
652: return FALSE;
653: }
654:
655: METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*,
656: private_mem_cred_t *this)
657: {
658: this->lock->read_lock(this->lock);
659: return enumerator_create_filter(
660: this->shared->create_enumerator(this->shared),
661: unique_filter, this->lock,
662: (void*)this->lock->unlock);
663: }
664:
665: /**
666: * Certificate distribution point
667: */
668: typedef struct {
669: certificate_type_t type;
670: identification_t *id;
671: char *uri;
672: } cdp_t;
673:
674: /**
675: * Destroy a CDP entry
676: */
677: static void cdp_destroy(cdp_t *this)
678: {
679: this->id->destroy(this->id);
680: free(this->uri);
681: free(this);
682: }
683:
684: METHOD(mem_cred_t, add_cdp, void,
685: private_mem_cred_t *this, certificate_type_t type,
686: identification_t *id, char *uri)
687: {
688: cdp_t *cdp;
689:
690: INIT(cdp,
691: .type = type,
692: .id = id->clone(id),
693: .uri = strdup(uri),
694: );
695: this->lock->write_lock(this->lock);
696: this->cdps->insert_last(this->cdps, cdp);
697: this->lock->unlock(this->lock);
698: }
699:
700: /**
701: * CDP enumerator data
702: */
703: typedef struct {
704: certificate_type_t type;
705: identification_t *id;
706: rwlock_t *lock;
707: } cdp_data_t;
708:
709: CALLBACK(cdp_data_destroy, void,
710: cdp_data_t *data)
711: {
712: data->lock->unlock(data->lock);
713: free(data);
714: }
715:
716: CALLBACK(cdp_filter, bool,
717: cdp_data_t *data, enumerator_t *orig, va_list args)
718: {
719: cdp_t *cdp;
720: char **uri;
721:
722: VA_ARGS_VGET(args, uri);
723:
724: while (orig->enumerate(orig, &cdp))
725: {
726: if (data->type != CERT_ANY && data->type != cdp->type)
727: {
728: continue;
729: }
730: if (data->id && !cdp->id->matches(cdp->id, data->id))
731: {
732: continue;
733: }
734: *uri = cdp->uri;
735: return TRUE;
736: }
737: return FALSE;
738: }
739:
740: METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
741: private_mem_cred_t *this, certificate_type_t type, identification_t *id)
742: {
743: cdp_data_t *data;
744:
745: INIT(data,
746: .type = type,
747: .id = id,
748: .lock = this->lock,
749: );
750: this->lock->read_lock(this->lock);
751: return enumerator_create_filter(this->cdps->create_enumerator(this->cdps),
752: cdp_filter, data, cdp_data_destroy);
753:
754: }
755:
756: static void reset_certs(private_mem_cred_t *this)
757: {
758: this->trusted->destroy_offset(this->trusted,
759: offsetof(certificate_t, destroy));
760: this->untrusted->destroy_offset(this->untrusted,
761: offsetof(certificate_t, destroy));
762: this->trusted = linked_list_create();
763: this->untrusted = linked_list_create();
764: }
765:
766: static void copy_certs(linked_list_t *dst, linked_list_t *src, bool clone)
767: {
768: enumerator_t *enumerator;
769: certificate_t *cert;
770:
771: enumerator = src->create_enumerator(src);
772: while (enumerator->enumerate(enumerator, &cert))
773: {
774: if (clone)
775: {
776: cert = cert->get_ref(cert);
777: }
778: else
779: {
780: src->remove_at(src, enumerator);
781: }
782: dst->insert_last(dst, cert);
783: }
784: enumerator->destroy(enumerator);
785: }
786:
787: METHOD(mem_cred_t, replace_certs, void,
788: private_mem_cred_t *this, mem_cred_t *other_set, bool clone)
789: {
790: private_mem_cred_t *other = (private_mem_cred_t*)other_set;
791:
792: this->lock->write_lock(this->lock);
793: reset_certs(this);
794: copy_certs(this->untrusted, other->untrusted, clone);
795: copy_certs(this->trusted, other->trusted, clone);
796: this->lock->unlock(this->lock);
797: }
798:
799: static void reset_secrets(private_mem_cred_t *this)
800: {
801: this->keys->destroy_offset(this->keys, offsetof(private_key_t, destroy));
802: this->shared->destroy_function(this->shared, (void*)shared_entry_destroy);
803: this->keys = linked_list_create();
804: this->shared = linked_list_create();
805: }
806:
807: METHOD(mem_cred_t, replace_secrets, void,
808: private_mem_cred_t *this, mem_cred_t *other_set, bool clone)
809: {
810: private_mem_cred_t *other = (private_mem_cred_t*)other_set;
811: enumerator_t *enumerator;
812: shared_entry_t *entry, *new_entry;
813: private_key_t *key;
814:
815: this->lock->write_lock(this->lock);
816:
817: reset_secrets(this);
818:
819: if (clone)
820: {
821: enumerator = other->keys->create_enumerator(other->keys);
822: while (enumerator->enumerate(enumerator, &key))
823: {
824: this->keys->insert_last(this->keys, key->get_ref(key));
825: }
826: enumerator->destroy(enumerator);
827: enumerator = other->shared->create_enumerator(other->shared);
828: while (enumerator->enumerate(enumerator, &entry))
829: {
830: INIT(new_entry,
831: .shared = entry->shared->get_ref(entry->shared),
832: .owners = entry->owners->clone_offset(entry->owners,
833: offsetof(identification_t, clone)),
834: );
835: this->shared->insert_last(this->shared, new_entry);
836: }
837: enumerator->destroy(enumerator);
838: }
839: else
840: {
841: while (other->keys->remove_first(other->keys, (void**)&key) == SUCCESS)
842: {
843: this->keys->insert_last(this->keys, key);
844: }
845: while (other->shared->remove_first(other->shared,
846: (void**)&entry) == SUCCESS)
847: {
848: this->shared->insert_last(this->shared, entry);
849: }
850: }
851: this->lock->unlock(this->lock);
852: }
853:
854: METHOD(mem_cred_t, clear_secrets, void,
855: private_mem_cred_t *this)
856: {
857: this->lock->write_lock(this->lock);
858: reset_secrets(this);
859: this->lock->unlock(this->lock);
860: }
861:
862: METHOD(mem_cred_t, clear_, void,
863: private_mem_cred_t *this)
864: {
865: this->lock->write_lock(this->lock);
866: this->cdps->destroy_function(this->cdps, (void*)cdp_destroy);
867: this->cdps = linked_list_create();
868: reset_certs(this);
869: reset_secrets(this);
870: this->lock->unlock(this->lock);
871: }
872:
873: METHOD(mem_cred_t, destroy, void,
874: private_mem_cred_t *this)
875: {
876: clear_(this);
877: this->trusted->destroy(this->trusted);
878: this->untrusted->destroy(this->untrusted);
879: this->keys->destroy(this->keys);
880: this->shared->destroy(this->shared);
881: this->cdps->destroy(this->cdps);
882: this->lock->destroy(this->lock);
883: free(this);
884: }
885:
886: /**
887: * See header
888: */
889: mem_cred_t *mem_cred_create()
890: {
891: private_mem_cred_t *this;
892:
893: INIT(this,
894: .public = {
895: .set = {
896: .create_shared_enumerator = _create_shared_enumerator,
897: .create_private_enumerator = _create_private_enumerator,
898: .create_cert_enumerator = _create_cert_enumerator,
899: .create_cdp_enumerator = _create_cdp_enumerator,
900: .cache_cert = (void*)nop,
901: },
902: .add_cert = _add_cert,
903: .add_cert_ref = _add_cert_ref,
904: .get_cert_ref = _get_cert_ref,
905: .add_crl = _add_crl,
906: .add_key = _add_key,
907: .remove_key = _remove_key,
908: .add_shared = _add_shared,
909: .add_shared_list = _add_shared_list,
910: .add_shared_unique = _add_shared_unique,
911: .remove_shared_unique = _remove_shared_unique,
912: .create_unique_shared_enumerator = _create_unique_shared_enumerator,
913: .add_cdp = _add_cdp,
914: .replace_certs = _replace_certs,
915: .replace_secrets = _replace_secrets,
916: .clear = _clear_,
917: .clear_secrets = _clear_secrets,
918: .destroy = _destroy,
919: },
920: .trusted = linked_list_create(),
921: .untrusted = linked_list_create(),
922: .keys = linked_list_create(),
923: .shared = linked_list_create(),
924: .cdps = linked_list_create(),
925: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
926: );
927:
928: return &this->public;
929: }