Return to vici_authority.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / vici |
1.1 misho 1: /* 1.1.1.2 ! misho 2: * Copyright (C) 2016-2020 Tobias Brunner 1.1 misho 3: * Copyright (C) 2015 Andreas Steffen 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * This program is free software; you can redistribute it and/or modify it 7: * under the terms of the GNU General Public License as published by the 8: * Free Software Foundation; either version 2 of the License, or (at your 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10: * 11: * This program is distributed in the hope that it will be useful, but 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14: * for more details. 15: */ 16: 17: #define _GNU_SOURCE 18: 19: #include "vici_authority.h" 20: #include "vici_builder.h" 21: 22: #include <threading/rwlock.h> 23: #include <collections/linked_list.h> 24: #include <credentials/certificates/x509.h> 25: #include <utils/debug.h> 26: 27: #include <stdio.h> 28: 29: typedef struct private_vici_authority_t private_vici_authority_t; 30: 31: /** 32: * Private data of an vici_authority_t object. 33: */ 34: struct private_vici_authority_t { 35: 36: /** 37: * Public vici_authority_t interface. 38: */ 39: vici_authority_t public; 40: 41: /** 42: * Dispatcher 43: */ 44: vici_dispatcher_t *dispatcher; 45: 46: /** 1.1.1.2 ! misho 47: * List of certification authorities (authority_t*) 1.1 misho 48: */ 1.1.1.2 ! misho 49: linked_list_t *authorities; 1.1 misho 50: 51: /** 1.1.1.2 ! misho 52: * List of CA certificates (ca_cert_t*) 1.1 misho 53: */ 1.1.1.2 ! misho 54: linked_list_t *certs; 1.1 misho 55: 56: /** 57: * rwlock to lock access to certification authorities 58: */ 59: rwlock_t *lock; 60: 61: }; 62: 63: typedef struct authority_t authority_t; 64: 65: /** 66: * loaded certification authorities 67: */ 68: struct authority_t { 69: 70: /** 71: * Name of the certification authority 72: */ 73: char *name; 74: 75: /** 76: * Reference to CA certificate 77: */ 78: certificate_t *cert; 79: 80: /** 81: * CRL URIs 82: */ 83: linked_list_t *crl_uris; 84: 85: /** 86: * OCSP URIs 87: */ 88: linked_list_t *ocsp_uris; 89: 90: /** 91: * Base URI used for certificates from this CA 92: */ 93: char *cert_uri_base; 94: }; 95: 96: /** 97: * create a new certification authority 98: */ 99: static authority_t *authority_create(char *name) 100: { 101: authority_t *authority; 102: 103: INIT(authority, 104: .name = strdup(name), 105: .crl_uris = linked_list_create(), 106: .ocsp_uris = linked_list_create(), 107: ); 108: 109: return authority; 110: } 111: 1.1.1.2 ! misho 112: CALLBACK(authority_destroy, void, ! 113: authority_t *this) 1.1 misho 114: { 115: this->crl_uris->destroy_function(this->crl_uris, free); 116: this->ocsp_uris->destroy_function(this->ocsp_uris, free); 117: DESTROY_IF(this->cert); 118: free(this->cert_uri_base); 119: free(this->name); 120: free(this); 121: } 122: 1.1.1.2 ! misho 123: typedef struct ca_cert_t ca_cert_t; ! 124: ! 125: /** ! 126: * Loaded CA certificate. ! 127: */ ! 128: struct ca_cert_t { ! 129: ! 130: /** ! 131: * Reference to certificate. ! 132: */ ! 133: certificate_t *cert; ! 134: ! 135: /** ! 136: * The number of authority sections referring to this certificate. ! 137: */ ! 138: u_int count; ! 139: ! 140: /** ! 141: * TRUE if this certificate was (also) added externally. ! 142: */ ! 143: bool external; ! 144: }; ! 145: ! 146: /** ! 147: * Destroy a CA certificate entry ! 148: */ ! 149: CALLBACK(ca_cert_destroy, void, ! 150: ca_cert_t *this) ! 151: { ! 152: this->cert->destroy(this->cert); ! 153: free(this); ! 154: } ! 155: ! 156: CALLBACK(match_cert, bool, ! 157: ca_cert_t *item, va_list args) ! 158: { ! 159: certificate_t *cert; ! 160: ! 161: VA_ARGS_VGET(args, cert); ! 162: return cert->equals(cert, item->cert); ! 163: } ! 164: ! 165: /** ! 166: * Add a CA certificate to the local store ! 167: */ ! 168: static certificate_t *add_cert_internal(private_vici_authority_t *this, ! 169: certificate_t *cert, bool external) ! 170: { ! 171: ca_cert_t *found; ! 172: ! 173: if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert)) ! 174: { ! 175: cert->destroy(cert); ! 176: cert = found->cert->get_ref(found->cert); ! 177: } ! 178: else ! 179: { ! 180: INIT(found, ! 181: .cert = cert->get_ref(cert) ! 182: ); ! 183: this->certs->insert_first(this->certs, found); ! 184: } ! 185: if (external) ! 186: { ! 187: found->external = TRUE; ! 188: } ! 189: else ! 190: { ! 191: found->count++; ! 192: } ! 193: return cert; ! 194: } ! 195: ! 196: CALLBACK(remove_external_certs, bool, ! 197: ca_cert_t *item, void *unused) ! 198: { ! 199: if (item->external) ! 200: { ! 201: item->external = FALSE; ! 202: ! 203: if (!item->count) ! 204: { ! 205: ca_cert_destroy(item); ! 206: return TRUE; ! 207: } ! 208: } ! 209: return FALSE; ! 210: } ! 211: ! 212: CALLBACK2(remove_cert, bool, ! 213: ca_cert_t *item, certificate_t *cert) ! 214: { ! 215: if (cert == item->cert) ! 216: { ! 217: if (--item->count == 0 && !item->external) ! 218: { ! 219: ca_cert_destroy(item); ! 220: return TRUE; ! 221: } ! 222: } ! 223: return FALSE; ! 224: } 1.1 misho 225: 226: /** 227: * Create a (error) reply message 228: */ 229: static vici_message_t* create_reply(char *fmt, ...) 230: { 231: vici_builder_t *builder; 232: va_list args; 233: 234: builder = vici_builder_create(); 235: builder->add_kv(builder, "success", fmt ? "no" : "yes"); 236: if (fmt) 237: { 238: va_start(args, fmt); 239: builder->vadd_kv(builder, "errmsg", fmt, args); 240: va_end(args); 241: } 242: return builder->finalize(builder); 243: } 244: 245: /** 246: * A rule to parse a key/value or list item 247: */ 248: typedef struct { 249: /** name of the key/value or list */ 250: char *name; 251: /** function to parse value */ 252: bool (*parse)(void *out, chunk_t value); 253: /** result, passed to parse() */ 254: void *out; 255: } parse_rule_t; 256: 257: /** 258: * Parse key/values using a rule-set 259: */ 260: static bool parse_rules(parse_rule_t *rules, int count, char *name, 261: chunk_t value, vici_message_t **reply) 262: { 263: int i; 264: 265: for (i = 0; i < count; i++) 266: { 267: if (streq(name, rules[i].name)) 268: { 269: if (rules[i].parse(rules[i].out, value)) 270: { 271: return TRUE; 272: } 273: *reply = create_reply("invalid value for: %s, authority discarded", 274: name); 275: return FALSE; 276: } 277: } 278: *reply = create_reply("unknown option: %s, authority discarded", name); 279: return FALSE; 280: } 281: 282: /** 283: * Parse callback data, passed to each callback 284: */ 285: typedef struct { 286: private_vici_authority_t *this; 287: vici_message_t *reply; 288: } request_data_t; 289: 290: /** 291: * Data associated with an authority load 292: */ 293: typedef struct { 294: request_data_t *request; 295: authority_t *authority; 296: char *handle; 297: uint32_t slot; 298: char *module; 299: char *file; 300: } load_data_t; 301: 302: /** 303: * Clean up data associated with an authority load 304: */ 305: static void free_load_data(load_data_t *data) 306: { 307: if (data->authority) 308: { 309: authority_destroy(data->authority); 310: } 311: free(data->handle); 312: free(data->module); 313: free(data->file); 314: free(data); 315: } 316: 317: /** 318: * Parse a string 319: */ 320: CALLBACK(parse_string, bool, 321: char **str, chunk_t v) 322: { 323: if (!chunk_printable(v, NULL, ' ')) 324: { 325: return FALSE; 326: } 327: *str = strndup(v.ptr, v.len); 328: 329: return TRUE; 330: } 331: 332: /** 333: * Parse a uint32_t 334: */ 335: CALLBACK(parse_uint32, bool, 336: uint32_t *out, chunk_t v) 337: { 338: char buf[16], *end; 339: u_long l; 340: 341: if (!vici_stringify(v, buf, sizeof(buf))) 342: { 343: return FALSE; 344: } 345: l = strtoul(buf, &end, 0); 346: if (*end == 0) 347: { 348: *out = l; 349: return TRUE; 350: } 351: return FALSE; 352: } 353: 354: /** 355: * Parse list of URIs 356: */ 357: CALLBACK(parse_uris, bool, 358: linked_list_t *out, chunk_t v) 359: { 360: char *uri; 361: 362: if (!chunk_printable(v, NULL, ' ')) 363: { 364: return FALSE; 365: } 366: uri = strndup(v.ptr, v.len); 367: out->insert_last(out, uri); 368: 369: return TRUE; 370: } 371: 372: /** 373: * Parse a CA certificate 374: */ 375: CALLBACK(parse_cacert, bool, 376: certificate_t **cacert, chunk_t v) 377: { 378: certificate_t *cert; 379: x509_t *x509; 380: 381: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, 382: BUILD_BLOB_PEM, v, BUILD_END); 383: if (!cert) 384: { 385: return create_reply("parsing %N certificate failed", 386: certificate_type_names, CERT_X509); 387: } 388: x509 = (x509_t*)cert; 389: 390: if ((x509->get_flags(x509) & X509_CA) != X509_CA) 391: { 392: cert->destroy(cert); 393: return create_reply("certificate without CA flag, rejected"); 394: } 395: *cacert = cert; 396: 397: return TRUE; 398: } 399: 400: CALLBACK(authority_kv, bool, 401: load_data_t *data, vici_message_t *message, char *name, chunk_t value) 402: { 403: parse_rule_t rules[] = { 404: { "cacert", parse_cacert, &data->authority->cert }, 405: { "file", parse_string, &data->file }, 406: { "handle", parse_string, &data->handle }, 407: { "slot", parse_uint32, &data->slot }, 408: { "module", parse_string, &data->module }, 409: { "cert_uri_base", parse_string, &data->authority->cert_uri_base }, 410: }; 411: 412: return parse_rules(rules, countof(rules), name, value, 413: &data->request->reply); 414: } 415: 416: CALLBACK(authority_li, bool, 417: load_data_t *data, vici_message_t *message, char *name, chunk_t value) 418: { 419: parse_rule_t rules[] = { 420: { "crl_uris", parse_uris, data->authority->crl_uris }, 421: { "ocsp_uris", parse_uris, data->authority->ocsp_uris }, 422: }; 423: 424: return parse_rules(rules, countof(rules), name, value, 425: &data->request->reply); 426: } 427: 428: static void log_authority_data(authority_t *authority) 429: { 430: enumerator_t *enumerator; 431: identification_t *subject; 432: bool first = TRUE; 433: char *uri; 434: 435: subject = authority->cert->get_subject(authority->cert); 436: DBG2(DBG_CFG, " cacert = %Y", subject); 437: 438: enumerator = authority->crl_uris->create_enumerator(authority->crl_uris); 439: while (enumerator->enumerate(enumerator, &uri)) 440: { 441: if (first) 442: { 443: DBG2(DBG_CFG, " crl_uris = %s", uri); 444: first = FALSE; 445: } 446: else 447: { 448: DBG2(DBG_CFG, " %s", uri); 449: } 450: } 451: enumerator->destroy(enumerator); 452: 453: first = TRUE; 454: enumerator = authority->ocsp_uris->create_enumerator(authority->ocsp_uris); 455: while (enumerator->enumerate(enumerator, &uri)) 456: { 457: if (first) 458: { 459: DBG2(DBG_CFG, " ocsp_uris = %s", uri); 460: first = FALSE; 461: } 462: else 463: { 464: DBG2(DBG_CFG, " %s", uri); 465: } 466: } 467: enumerator->destroy(enumerator); 468: 469: if (authority->cert_uri_base) 470: { 471: DBG2(DBG_CFG, " cert_uri_base = %s", authority->cert_uri_base); 472: } 473: } 474: 475: CALLBACK(authority_sn, bool, 476: request_data_t *request, vici_message_t *message, 477: vici_parse_context_t *ctx, char *name) 478: { 479: enumerator_t *enumerator; 480: linked_list_t *authorities; 481: authority_t *authority; 482: load_data_t *data; 483: chunk_t handle; 484: 485: INIT(data, 486: .request = request, 487: .authority = authority_create(name), 488: .slot = -1, 489: ); 490: 491: DBG2(DBG_CFG, " authority %s:", name); 492: 493: if (!message->parse(message, ctx, NULL, authority_kv, authority_li, data)) 494: { 495: free_load_data(data); 496: return FALSE; 497: } 498: if (!data->authority->cert) 499: { 500: if (data->file) 501: { 502: data->authority->cert = lib->creds->create(lib->creds, 503: CRED_CERTIFICATE, CERT_X509, 504: BUILD_FROM_FILE, data->file, BUILD_END); 505: } 506: else if (data->handle) 507: { 508: handle = chunk_from_hex(chunk_from_str(data->handle), NULL); 509: if (data->slot != -1) 510: { 511: data->authority->cert = lib->creds->create(lib->creds, 512: CRED_CERTIFICATE, CERT_X509, 513: BUILD_PKCS11_KEYID, handle, 514: BUILD_PKCS11_SLOT, data->slot, 515: data->module ? BUILD_PKCS11_MODULE : BUILD_END, 516: data->module, BUILD_END); 517: } 518: else 519: { 520: data->authority->cert = lib->creds->create(lib->creds, 521: CRED_CERTIFICATE, CERT_X509, 522: BUILD_PKCS11_KEYID, handle, 523: data->module ? BUILD_PKCS11_MODULE : BUILD_END, 524: data->module, BUILD_END); 525: } 526: chunk_free(&handle); 527: } 528: } 529: if (!data->authority->cert) 530: { 531: request->reply = create_reply("CA certificate missing: %s", name); 532: free_load_data(data); 533: return FALSE; 534: } 535: log_authority_data(data->authority); 536: 537: request->this->lock->write_lock(request->this->lock); 538: 1.1.1.2 ! misho 539: data->authority->cert = add_cert_internal(request->this, ! 540: data->authority->cert, FALSE); ! 541: 1.1 misho 542: authorities = request->this->authorities; 543: enumerator = authorities->create_enumerator(authorities); 544: while (enumerator->enumerate(enumerator, &authority)) 545: { 546: if (streq(authority->name, name)) 547: { 548: /* remove the old authority definition */ 549: authorities->remove_at(authorities, enumerator); 1.1.1.2 ! misho 550: request->this->certs->remove(request->this->certs, authority->cert, ! 551: remove_cert); 1.1 misho 552: authority_destroy(authority); 553: break; 554: } 555: } 556: enumerator->destroy(enumerator); 557: authorities->insert_last(authorities, data->authority); 558: 559: request->this->lock->unlock(request->this->lock); 1.1.1.2 ! misho 560: data->authority = NULL; 1.1 misho 561: free_load_data(data); 562: 563: return TRUE; 564: } 565: 566: CALLBACK(load_authority, vici_message_t*, 567: private_vici_authority_t *this, char *name, u_int id, vici_message_t *message) 568: { 569: request_data_t request = { 570: .this = this, 571: }; 572: 573: if (!message->parse(message, NULL, authority_sn, NULL, NULL, &request)) 574: { 575: if (request.reply) 576: { 577: return request.reply; 578: } 579: return create_reply("parsing request failed"); 580: } 581: return create_reply(NULL); 582: } 583: 584: CALLBACK(unload_authority, vici_message_t*, 585: private_vici_authority_t *this, char *name, u_int id, vici_message_t *message) 586: { 587: enumerator_t *enumerator; 588: authority_t *authority; 589: char *authority_name; 590: bool found = FALSE; 591: 592: authority_name = message->get_str(message, NULL, "name"); 593: if (!authority_name) 594: { 595: return create_reply("unload: missing authority name"); 596: } 597: 598: this->lock->write_lock(this->lock); 599: enumerator = this->authorities->create_enumerator(this->authorities); 600: while (enumerator->enumerate(enumerator, &authority)) 601: { 602: if (streq(authority->name, authority_name)) 603: { 604: this->authorities->remove_at(this->authorities, enumerator); 1.1.1.2 ! misho 605: this->certs->remove(this->certs, authority->cert, remove_cert); 1.1 misho 606: authority_destroy(authority); 607: found = TRUE; 608: break; 609: } 610: } 611: enumerator->destroy(enumerator); 612: this->lock->unlock(this->lock); 613: 614: if (!found) 615: { 616: return create_reply("unload: authority '%s' not found", authority_name); 617: } 1.1.1.2 ! misho 618: lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); 1.1 misho 619: return create_reply(NULL); 620: } 621: 622: CALLBACK(get_authorities, vici_message_t*, 623: private_vici_authority_t *this, char *name, u_int id, 624: vici_message_t *message) 625: { 626: vici_builder_t *builder; 627: enumerator_t *enumerator; 628: authority_t *authority; 629: 630: builder = vici_builder_create(); 631: builder->begin_list(builder, "authorities"); 632: 633: this->lock->read_lock(this->lock); 634: enumerator = this->authorities->create_enumerator(this->authorities); 635: while (enumerator->enumerate(enumerator, &authority)) 636: { 637: builder->add_li(builder, "%s", authority->name); 638: } 639: enumerator->destroy(enumerator); 640: this->lock->unlock(this->lock); 641: 642: builder->end_list(builder); 643: 644: return builder->finalize(builder); 645: } 646: 647: CALLBACK(list_authorities, vici_message_t*, 648: private_vici_authority_t *this, char *name, u_int id, vici_message_t *request) 649: { 650: enumerator_t *enumerator, *e; 651: authority_t *authority; 652: vici_builder_t *b; 653: char *str, *uri; 654: 655: str = request->get_str(request, NULL, "name"); 656: 657: this->lock->read_lock(this->lock); 658: enumerator = this->authorities->create_enumerator(this->authorities); 659: while (enumerator->enumerate(enumerator, &authority)) 660: { 661: if (str && !streq(str, authority->name)) 662: { 663: continue; 664: } 665: b = vici_builder_create(); 666: 667: /* open authority section */ 668: b->begin_section(b, authority->name); 669: 670: /* subject DN of cacert */ 671: b->add_kv(b, "cacert", "%Y", 672: authority->cert->get_subject(authority->cert)); 673: 674: /* list of crl_uris */ 675: b->begin_list(b, "crl_uris"); 676: e = authority->crl_uris->create_enumerator(authority->crl_uris); 677: while (e->enumerate(e, &uri)) 678: { 679: b->add_li(b, "%s", uri); 680: } 681: e->destroy(e); 682: b->end_list(b); 683: 684: /* list of ocsp_uris */ 685: b->begin_list(b, "ocsp_uris"); 686: e = authority->ocsp_uris->create_enumerator(authority->ocsp_uris); 687: while (e->enumerate(e, &uri)) 688: { 689: b->add_li(b, "%s", uri); 690: } 691: e->destroy(e); 692: b->end_list(b); 693: 694: /* cert_uri_base */ 695: if (authority->cert_uri_base) 696: { 697: b->add_kv(b, "cert_uri_base", "%s", authority->cert_uri_base); 698: } 699: 700: /* close authority and raise event */ 701: b->end_section(b); 702: this->dispatcher->raise_event(this->dispatcher, "list-authority", id, 703: b->finalize(b)); 704: } 705: enumerator->destroy(enumerator); 706: this->lock->unlock(this->lock); 707: 708: b = vici_builder_create(); 709: return b->finalize(b); 710: } 711: 712: static void manage_command(private_vici_authority_t *this, 713: char *name, vici_command_cb_t cb, bool reg) 714: { 715: this->dispatcher->manage_command(this->dispatcher, name, 716: reg ? cb : NULL, this); 717: } 718: 719: /** 720: * (Un-)register dispatcher functions 721: */ 722: static void manage_commands(private_vici_authority_t *this, bool reg) 723: { 724: this->dispatcher->manage_event(this->dispatcher, "list-authority", reg); 725: 726: manage_command(this, "load-authority", load_authority, reg); 727: manage_command(this, "unload-authority", unload_authority, reg); 728: manage_command(this, "get-authorities", get_authorities, reg); 729: manage_command(this, "list-authorities", list_authorities, reg); 730: } 731: 732: /** 1.1.1.2 ! misho 733: * Data for the certificate and CDP enumerator 1.1 misho 734: */ 735: typedef struct { 736: private_vici_authority_t *this; 737: certificate_type_t type; 1.1.1.2 ! misho 738: key_type_t key; 1.1 misho 739: identification_t *id; 1.1.1.2 ! misho 740: } cert_data_t; 1.1 misho 741: 1.1.1.2 ! misho 742: CALLBACK(cert_data_destroy, void, ! 743: cert_data_t *data) 1.1 misho 744: { 745: data->this->lock->unlock(data->this->lock); 746: free(data); 747: } 748: 1.1.1.2 ! misho 749: CALLBACK(certs_filter, bool, ! 750: cert_data_t *data, enumerator_t *orig, va_list args) ! 751: { ! 752: ca_cert_t *ca; ! 753: certificate_t **out; ! 754: ! 755: VA_ARGS_VGET(args, out); ! 756: ! 757: while (orig->enumerate(orig, &ca)) ! 758: { ! 759: if (certificate_matches(ca->cert, data->type, data->key, data->id)) ! 760: { ! 761: *out = ca->cert; ! 762: return TRUE; ! 763: } ! 764: } ! 765: return FALSE; ! 766: } ! 767: ! 768: METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, ! 769: private_vici_authority_t *this, certificate_type_t cert, key_type_t key, ! 770: identification_t *id, bool trusted) ! 771: { ! 772: enumerator_t *enumerator; ! 773: cert_data_t *data; ! 774: ! 775: INIT(data, ! 776: .this = this, ! 777: .type = cert, ! 778: .key = key, ! 779: .id = id, ! 780: ); ! 781: ! 782: this->lock->read_lock(this->lock); ! 783: enumerator = this->certs->create_enumerator(this->certs); ! 784: return enumerator_create_filter(enumerator, certs_filter, data, ! 785: cert_data_destroy); ! 786: } ! 787: ! 788: CALLBACK(create_inner_cdp, enumerator_t*, ! 789: authority_t *authority, cert_data_t *data) 1.1 misho 790: { 791: public_key_t *public; 792: enumerator_t *enumerator = NULL; 793: linked_list_t *list; 794: 795: if (data->type == CERT_X509_OCSP_RESPONSE) 796: { 797: list = authority->ocsp_uris; 798: } 799: else 800: { 801: list = authority->crl_uris; 802: } 803: 804: public = authority->cert->get_public_key(authority->cert); 805: if (public) 806: { 807: if (!data->id) 808: { 809: enumerator = list->create_enumerator(list); 810: } 811: else 812: { 1.1.1.2 ! misho 813: if (public->has_fingerprint(public, ! 814: data->id->get_encoding(data->id))) 1.1 misho 815: { 816: enumerator = list->create_enumerator(list); 817: } 818: } 819: public->destroy(public); 820: } 821: return enumerator; 822: } 823: 1.1.1.2 ! misho 824: CALLBACK(create_inner_cdp_hashandurl, enumerator_t*, ! 825: authority_t *authority, cert_data_t *data) 1.1 misho 826: { 827: enumerator_t *enumerator = NULL; 828: 829: if (!data->id || !authority->cert_uri_base) 830: { 831: return NULL; 832: } 833: 1.1.1.2 ! misho 834: if (authority->cert->has_subject(authority->cert, ! 835: data->id) != ID_MATCH_NONE) 1.1 misho 836: { 837: enumerator = enumerator_create_single(strdup(authority->cert_uri_base), 838: free); 839: } 840: return enumerator; 841: } 842: 843: METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, 844: private_vici_authority_t *this, certificate_type_t type, 845: identification_t *id) 846: { 1.1.1.2 ! misho 847: cert_data_t *data; 1.1 misho 848: 849: switch (type) 850: { /* we serve CRLs, OCSP responders and URLs for "Hash and URL" */ 851: case CERT_X509: 852: case CERT_X509_CRL: 853: case CERT_X509_OCSP_RESPONSE: 854: case CERT_ANY: 855: break; 856: default: 857: return NULL; 858: } 859: 1.1.1.2 ! misho 860: INIT(data, ! 861: .this = this, ! 862: .type = type, ! 863: .id = id, ! 864: ); 1.1 misho 865: 1.1.1.2 ! misho 866: this->lock->read_lock(this->lock); 1.1 misho 867: return enumerator_create_nested( 868: this->authorities->create_enumerator(this->authorities), 869: (type == CERT_X509) ? (void*)create_inner_cdp_hashandurl : 1.1.1.2 ! misho 870: (void*)create_inner_cdp, data, cert_data_destroy); ! 871: } ! 872: ! 873: METHOD(vici_authority_t, add_ca_cert, certificate_t*, ! 874: private_vici_authority_t *this, certificate_t *cert) ! 875: { ! 876: this->lock->write_lock(this->lock); ! 877: cert = add_cert_internal(this, cert, TRUE); ! 878: this->lock->unlock(this->lock); ! 879: return cert; ! 880: } ! 881: ! 882: METHOD(vici_authority_t, clear_ca_certs, void, ! 883: private_vici_authority_t *this) ! 884: { ! 885: this->lock->write_lock(this->lock); ! 886: this->certs->remove(this->certs, NULL, remove_external_certs); ! 887: this->lock->unlock(this->lock); 1.1 misho 888: } 889: 890: METHOD(vici_authority_t, destroy, void, 891: private_vici_authority_t *this) 892: { 893: manage_commands(this, FALSE); 894: 895: this->authorities->destroy_function(this->authorities, 896: (void*)authority_destroy); 1.1.1.2 ! misho 897: this->certs->destroy_function(this->certs, ca_cert_destroy); 1.1 misho 898: this->lock->destroy(this->lock); 899: free(this); 900: } 901: 902: /** 903: * See header 904: */ 1.1.1.2 ! misho 905: vici_authority_t *vici_authority_create(vici_dispatcher_t *dispatcher) 1.1 misho 906: { 907: private_vici_authority_t *this; 908: 909: INIT(this, 910: .public = { 911: .set = { 912: .create_private_enumerator = (void*)return_null, 1.1.1.2 ! misho 913: .create_cert_enumerator = _create_cert_enumerator, 1.1 misho 914: .create_shared_enumerator = (void*)return_null, 915: .create_cdp_enumerator = _create_cdp_enumerator, 916: .cache_cert = (void*)nop, 917: }, 1.1.1.2 ! misho 918: .add_ca_cert = _add_ca_cert, ! 919: .clear_ca_certs = _clear_ca_certs, 1.1 misho 920: .destroy = _destroy, 921: }, 922: .dispatcher = dispatcher, 923: .authorities = linked_list_create(), 1.1.1.2 ! misho 924: .certs = linked_list_create(), 1.1 misho 925: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), 926: ); 927: 928: manage_commands(this, TRUE); 929: 930: return &this->public; 931: }