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: 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: }