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