Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_authority.c, revision 1.1.1.2
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>