Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_authority.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2016-2019 Tobias Brunner
                      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:        /**
                     47:         * credential backend managed by VICI used for our ca certificates
                     48:         */
                     49:        vici_cred_t *cred;
                     50: 
                     51:        /**
                     52:         * List of certification authorities
                     53:         */
                     54:        linked_list_t *authorities;
                     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: 
                    112: /**
                    113:  * destroy a certification authority
                    114:  */
                    115: static void authority_destroy(authority_t *this)
                    116: {
                    117:        this->crl_uris->destroy_function(this->crl_uris, free);
                    118:        this->ocsp_uris->destroy_function(this->ocsp_uris, free);
                    119:        DESTROY_IF(this->cert);
                    120:        free(this->cert_uri_base);
                    121:        free(this->name);
                    122:        free(this);
                    123: }
                    124: 
                    125: 
                    126: /**
                    127:  * Create a (error) reply message
                    128:  */
                    129: static vici_message_t* create_reply(char *fmt, ...)
                    130: {
                    131:        vici_builder_t *builder;
                    132:        va_list args;
                    133: 
                    134:        builder = vici_builder_create();
                    135:        builder->add_kv(builder, "success", fmt ? "no" : "yes");
                    136:        if (fmt)
                    137:        {
                    138:                va_start(args, fmt);
                    139:                builder->vadd_kv(builder, "errmsg", fmt, args);
                    140:                va_end(args);
                    141:        }
                    142:        return builder->finalize(builder);
                    143: }
                    144: 
                    145: /**
                    146:  * A rule to parse a key/value or list item
                    147:  */
                    148: typedef struct {
                    149:        /** name of the key/value or list */
                    150:        char *name;
                    151:        /** function to parse value */
                    152:        bool (*parse)(void *out, chunk_t value);
                    153:        /** result, passed to parse() */
                    154:        void *out;
                    155: } parse_rule_t;
                    156: 
                    157: /**
                    158:  * Parse key/values using a rule-set
                    159:  */
                    160: static bool parse_rules(parse_rule_t *rules, int count, char *name,
                    161:                                                chunk_t value, vici_message_t **reply)
                    162: {
                    163:        int i;
                    164: 
                    165:        for (i = 0; i < count; i++)
                    166:        {
                    167:                if (streq(name, rules[i].name))
                    168:                {
                    169:                        if (rules[i].parse(rules[i].out, value))
                    170:                        {
                    171:                                return TRUE;
                    172:                        }
                    173:                        *reply = create_reply("invalid value for: %s, authority discarded",
                    174:                                                                  name);
                    175:                        return FALSE;
                    176:                }
                    177:        }
                    178:        *reply = create_reply("unknown option: %s, authority discarded", name);
                    179:        return FALSE;
                    180: }
                    181: 
                    182: /**
                    183:  * Parse callback data, passed to each callback
                    184:  */
                    185: typedef struct {
                    186:        private_vici_authority_t *this;
                    187:        vici_message_t *reply;
                    188: } request_data_t;
                    189: 
                    190: /**
                    191:  * Data associated with an authority load
                    192:  */
                    193: typedef struct {
                    194:        request_data_t *request;
                    195:        authority_t *authority;
                    196:        char *handle;
                    197:        uint32_t slot;
                    198:        char *module;
                    199:        char *file;
                    200: } load_data_t;
                    201: 
                    202: /**
                    203:  * Clean up data associated with an authority load
                    204:  */
                    205: static void free_load_data(load_data_t *data)
                    206: {
                    207:        if (data->authority)
                    208:        {
                    209:                authority_destroy(data->authority);
                    210:        }
                    211:        free(data->handle);
                    212:        free(data->module);
                    213:        free(data->file);
                    214:        free(data);
                    215: }
                    216: 
                    217: /**
                    218:  * Parse a string
                    219:  */
                    220: CALLBACK(parse_string, bool,
                    221:        char **str, chunk_t v)
                    222: {
                    223:        if (!chunk_printable(v, NULL, ' '))
                    224:        {
                    225:                return FALSE;
                    226:        }
                    227:        *str = strndup(v.ptr, v.len);
                    228: 
                    229:        return TRUE;
                    230: }
                    231: 
                    232: /**
                    233:  * Parse a uint32_t
                    234:  */
                    235: CALLBACK(parse_uint32, bool,
                    236:        uint32_t *out, chunk_t v)
                    237: {
                    238:        char buf[16], *end;
                    239:        u_long l;
                    240: 
                    241:        if (!vici_stringify(v, buf, sizeof(buf)))
                    242:        {
                    243:                return FALSE;
                    244:        }
                    245:        l = strtoul(buf, &end, 0);
                    246:        if (*end == 0)
                    247:        {
                    248:                *out = l;
                    249:                return TRUE;
                    250:        }
                    251:        return FALSE;
                    252: }
                    253: 
                    254: /**
                    255:  * Parse list of URIs
                    256:  */
                    257: CALLBACK(parse_uris, bool,
                    258:        linked_list_t *out, chunk_t v)
                    259: {
                    260:        char *uri;
                    261: 
                    262:        if (!chunk_printable(v, NULL, ' '))
                    263:        {
                    264:                return FALSE;
                    265:        }
                    266:        uri = strndup(v.ptr, v.len);
                    267:        out->insert_last(out, uri);
                    268: 
                    269:        return TRUE;
                    270: }
                    271: 
                    272: /**
                    273:  * Parse a CA certificate
                    274:  */
                    275: CALLBACK(parse_cacert, bool,
                    276:        certificate_t **cacert, chunk_t v)
                    277: {
                    278:        certificate_t *cert;
                    279:        x509_t *x509;
                    280: 
                    281:        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    282:                                                                                  BUILD_BLOB_PEM, v, BUILD_END);
                    283:        if (!cert)
                    284:        {
                    285:                return create_reply("parsing %N certificate failed",
                    286:                                                        certificate_type_names, CERT_X509);
                    287:        }
                    288:        x509 = (x509_t*)cert;
                    289: 
                    290:        if ((x509->get_flags(x509) & X509_CA) != X509_CA)
                    291:        {
                    292:                cert->destroy(cert);
                    293:                return create_reply("certificate without CA flag, rejected");
                    294:        }
                    295:        *cacert = cert;
                    296: 
                    297:        return TRUE;
                    298: }
                    299: 
                    300: CALLBACK(authority_kv, bool,
                    301:        load_data_t *data, vici_message_t *message, char *name, chunk_t value)
                    302: {
                    303:        parse_rule_t rules[] = {
                    304:                { "cacert",                     parse_cacert, &data->authority->cert                    },
                    305:                { "file",                       parse_string, &data->file                                               },
                    306:                { "handle",                     parse_string, &data->handle                                             },
                    307:                { "slot",                       parse_uint32, &data->slot                                               },
                    308:                { "module",                     parse_string, &data->module                                             },
                    309:                { "cert_uri_base",      parse_string, &data->authority->cert_uri_base   },
                    310:        };
                    311: 
                    312:        return parse_rules(rules, countof(rules), name, value,
                    313:                                           &data->request->reply);
                    314: }
                    315: 
                    316: CALLBACK(authority_li, bool,
                    317:        load_data_t *data, vici_message_t *message, char *name, chunk_t value)
                    318: {
                    319:        parse_rule_t rules[] = {
                    320:                { "crl_uris",   parse_uris, data->authority->crl_uris  },
                    321:                { "ocsp_uris",  parse_uris, data->authority->ocsp_uris },
                    322:        };
                    323: 
                    324:        return parse_rules(rules, countof(rules), name, value,
                    325:                                           &data->request->reply);
                    326: }
                    327: 
                    328: static void log_authority_data(authority_t *authority)
                    329: {
                    330:        enumerator_t *enumerator;
                    331:        identification_t *subject;
                    332:        bool first = TRUE;
                    333:        char *uri;
                    334: 
                    335:        subject = authority->cert->get_subject(authority->cert);
                    336:        DBG2(DBG_CFG, "  cacert = %Y", subject);
                    337: 
                    338:        enumerator = authority->crl_uris->create_enumerator(authority->crl_uris);
                    339:        while (enumerator->enumerate(enumerator, &uri))
                    340:        {
                    341:                if (first)
                    342:                {
                    343:                        DBG2(DBG_CFG, "  crl_uris = %s", uri);
                    344:                        first = FALSE;
                    345:                }
                    346:                else
                    347:                {
                    348:                        DBG2(DBG_CFG, "             %s", uri);
                    349:                }
                    350:        }
                    351:        enumerator->destroy(enumerator);
                    352: 
                    353:        first = TRUE;
                    354:        enumerator = authority->ocsp_uris->create_enumerator(authority->ocsp_uris);
                    355:        while (enumerator->enumerate(enumerator, &uri))
                    356:        {
                    357:                if (first)
                    358:                {
                    359:                        DBG2(DBG_CFG, "  ocsp_uris = %s", uri);
                    360:                        first = FALSE;
                    361:                }
                    362:                else
                    363:                {
                    364:                        DBG2(DBG_CFG, "              %s", uri);
                    365:                }
                    366:        }
                    367:        enumerator->destroy(enumerator);
                    368: 
                    369:        if (authority->cert_uri_base)
                    370:        {
                    371:                DBG2(DBG_CFG, "  cert_uri_base = %s", authority->cert_uri_base);
                    372:        }
                    373: }
                    374: 
                    375: CALLBACK(authority_sn, bool,
                    376:        request_data_t *request, vici_message_t *message,
                    377:        vici_parse_context_t *ctx, char *name)
                    378: {
                    379:        enumerator_t *enumerator;
                    380:        linked_list_t *authorities;
                    381:        authority_t *authority;
                    382:        vici_cred_t *cred;
                    383:        load_data_t *data;
                    384:        chunk_t handle;
                    385: 
                    386:        INIT(data,
                    387:                .request = request,
                    388:                .authority = authority_create(name),
                    389:                .slot = -1,
                    390:        );
                    391: 
                    392:        DBG2(DBG_CFG, " authority %s:", name);
                    393: 
                    394:        if (!message->parse(message, ctx, NULL, authority_kv, authority_li, data))
                    395:        {
                    396:                free_load_data(data);
                    397:                return FALSE;
                    398:        }
                    399:        if (!data->authority->cert)
                    400:        {
                    401:                if (data->file)
                    402:                {
                    403:                        data->authority->cert = lib->creds->create(lib->creds,
                    404:                                                                                CRED_CERTIFICATE, CERT_X509,
                    405:                                                                                BUILD_FROM_FILE, data->file, BUILD_END);
                    406:                }
                    407:                else if (data->handle)
                    408:                {
                    409:                        handle = chunk_from_hex(chunk_from_str(data->handle), NULL);
                    410:                        if (data->slot != -1)
                    411:                        {
                    412:                                data->authority->cert = lib->creds->create(lib->creds,
                    413:                                                                CRED_CERTIFICATE, CERT_X509,
                    414:                                                                BUILD_PKCS11_KEYID, handle,
                    415:                                                                BUILD_PKCS11_SLOT, data->slot,
                    416:                                                                data->module ? BUILD_PKCS11_MODULE : BUILD_END,
                    417:                                                                data->module, BUILD_END);
                    418:                        }
                    419:                        else
                    420:                        {
                    421:                                data->authority->cert = lib->creds->create(lib->creds,
                    422:                                                                CRED_CERTIFICATE, CERT_X509,
                    423:                                                                BUILD_PKCS11_KEYID, handle,
                    424:                                                                data->module ? BUILD_PKCS11_MODULE : BUILD_END,
                    425:                                                                data->module, BUILD_END);
                    426:                        }
                    427:                        chunk_free(&handle);
                    428:                }
                    429:        }
                    430:        if (!data->authority->cert)
                    431:        {
                    432:                request->reply = create_reply("CA certificate missing: %s", name);
                    433:                free_load_data(data);
                    434:                return FALSE;
                    435:        }
                    436:        log_authority_data(data->authority);
                    437: 
                    438:        request->this->lock->write_lock(request->this->lock);
                    439: 
                    440:        authorities = request->this->authorities;
                    441:        enumerator = authorities->create_enumerator(authorities);
                    442:        while (enumerator->enumerate(enumerator, &authority))
                    443:        {
                    444:                if (streq(authority->name, name))
                    445:                {
                    446:                        /* remove the old authority definition */
                    447:                        authorities->remove_at(authorities, enumerator);
                    448:                        authority_destroy(authority);
                    449:                        break;
                    450:                }
                    451:        }
                    452:        enumerator->destroy(enumerator);
                    453:        authorities->insert_last(authorities, data->authority);
                    454: 
                    455:        cred = request->this->cred;
                    456:        data->authority->cert = cred->add_cert(cred, data->authority->cert);
                    457:        data->authority = NULL;
                    458: 
                    459:        request->this->lock->unlock(request->this->lock);
                    460:        free_load_data(data);
                    461: 
                    462:        return TRUE;
                    463: }
                    464: 
                    465: CALLBACK(load_authority, vici_message_t*,
                    466:        private_vici_authority_t *this, char *name, u_int id, vici_message_t *message)
                    467: {
                    468:        request_data_t request = {
                    469:                .this = this,
                    470:        };
                    471: 
                    472:        if (!message->parse(message, NULL, authority_sn, NULL, NULL, &request))
                    473:        {
                    474:                if (request.reply)
                    475:                {
                    476:                        return request.reply;
                    477:                }
                    478:                return create_reply("parsing request failed");
                    479:        }
                    480:        return create_reply(NULL);
                    481: }
                    482: 
                    483: CALLBACK(unload_authority, vici_message_t*,
                    484:        private_vici_authority_t *this, char *name, u_int id, vici_message_t *message)
                    485: {
                    486:        enumerator_t *enumerator;
                    487:        authority_t *authority;
                    488:        char *authority_name;
                    489:        bool found = FALSE;
                    490: 
                    491:        authority_name = message->get_str(message, NULL, "name");
                    492:        if (!authority_name)
                    493:        {
                    494:                return create_reply("unload: missing authority name");
                    495:        }
                    496: 
                    497:        this->lock->write_lock(this->lock);
                    498:        enumerator = this->authorities->create_enumerator(this->authorities);
                    499:        while (enumerator->enumerate(enumerator, &authority))
                    500:        {
                    501:                if (streq(authority->name, authority_name))
                    502:                {
                    503:                        this->authorities->remove_at(this->authorities, enumerator);
                    504:                        authority_destroy(authority);
                    505:                        found = TRUE;
                    506:                        break;
                    507:                }
                    508:        }
                    509:        enumerator->destroy(enumerator);
                    510:        this->lock->unlock(this->lock);
                    511: 
                    512:        if (!found)
                    513:        {
                    514:                return create_reply("unload: authority '%s' not found", authority_name);
                    515:        }
                    516:        return create_reply(NULL);
                    517: }
                    518: 
                    519: CALLBACK(get_authorities, vici_message_t*,
                    520:        private_vici_authority_t *this, char *name, u_int id,
                    521:        vici_message_t *message)
                    522: {
                    523:        vici_builder_t *builder;
                    524:        enumerator_t *enumerator;
                    525:        authority_t *authority;
                    526: 
                    527:        builder = vici_builder_create();
                    528:        builder->begin_list(builder, "authorities");
                    529: 
                    530:        this->lock->read_lock(this->lock);
                    531:        enumerator = this->authorities->create_enumerator(this->authorities);
                    532:        while (enumerator->enumerate(enumerator, &authority))
                    533:        {
                    534:                builder->add_li(builder, "%s", authority->name);
                    535:        }
                    536:        enumerator->destroy(enumerator);
                    537:        this->lock->unlock(this->lock);
                    538: 
                    539:        builder->end_list(builder);
                    540: 
                    541:        return builder->finalize(builder);
                    542: }
                    543: 
                    544: CALLBACK(list_authorities, vici_message_t*,
                    545:        private_vici_authority_t *this, char *name, u_int id, vici_message_t *request)
                    546: {
                    547:        enumerator_t *enumerator, *e;
                    548:        authority_t *authority;
                    549:        vici_builder_t *b;
                    550:        char *str, *uri;
                    551: 
                    552:        str = request->get_str(request, NULL, "name");
                    553: 
                    554:        this->lock->read_lock(this->lock);
                    555:        enumerator = this->authorities->create_enumerator(this->authorities);
                    556:        while (enumerator->enumerate(enumerator, &authority))
                    557:        {
                    558:                if (str && !streq(str, authority->name))
                    559:                {
                    560:                        continue;
                    561:                }
                    562:                b = vici_builder_create();
                    563: 
                    564:                /* open authority section */
                    565:                b->begin_section(b, authority->name);
                    566: 
                    567:                /* subject DN of cacert */
                    568:                b->add_kv(b, "cacert", "%Y",
                    569:                                          authority->cert->get_subject(authority->cert));
                    570: 
                    571:                /* list of crl_uris */
                    572:                b->begin_list(b, "crl_uris");
                    573:                e = authority->crl_uris->create_enumerator(authority->crl_uris);
                    574:                while (e->enumerate(e, &uri))
                    575:                {
                    576:                        b->add_li(b, "%s", uri);
                    577:                }
                    578:                e->destroy(e);
                    579:                b->end_list(b);
                    580: 
                    581:                /* list of ocsp_uris */
                    582:                b->begin_list(b, "ocsp_uris");
                    583:                e = authority->ocsp_uris->create_enumerator(authority->ocsp_uris);
                    584:                while (e->enumerate(e, &uri))
                    585:                {
                    586:                        b->add_li(b, "%s", uri);
                    587:                }
                    588:                e->destroy(e);
                    589:                b->end_list(b);
                    590: 
                    591:                /* cert_uri_base */
                    592:                if (authority->cert_uri_base)
                    593:                {
                    594:                        b->add_kv(b, "cert_uri_base", "%s", authority->cert_uri_base);
                    595:                }
                    596: 
                    597:                /* close authority and raise event */
                    598:                b->end_section(b);
                    599:                this->dispatcher->raise_event(this->dispatcher, "list-authority", id,
                    600:                                                                          b->finalize(b));
                    601:        }
                    602:        enumerator->destroy(enumerator);
                    603:        this->lock->unlock(this->lock);
                    604: 
                    605:        b = vici_builder_create();
                    606:        return b->finalize(b);
                    607: }
                    608: 
                    609: static void manage_command(private_vici_authority_t *this,
                    610:                                                   char *name, vici_command_cb_t cb, bool reg)
                    611: {
                    612:        this->dispatcher->manage_command(this->dispatcher, name,
                    613:                                                                         reg ? cb : NULL, this);
                    614: }
                    615: 
                    616: /**
                    617:  * (Un-)register dispatcher functions
                    618:  */
                    619: static void manage_commands(private_vici_authority_t *this, bool reg)
                    620: {
                    621:        this->dispatcher->manage_event(this->dispatcher, "list-authority", reg);
                    622: 
                    623:        manage_command(this, "load-authority", load_authority, reg);
                    624:        manage_command(this, "unload-authority", unload_authority, reg);
                    625:        manage_command(this, "get-authorities", get_authorities, reg);
                    626:        manage_command(this, "list-authorities", list_authorities, reg);
                    627: }
                    628: 
                    629: /**
                    630:  * data to pass to create_inner_cdp
                    631:  */
                    632: typedef struct {
                    633:        private_vici_authority_t *this;
                    634:        certificate_type_t type;
                    635:        identification_t *id;
                    636: } cdp_data_t;
                    637: 
                    638: /**
                    639:  * destroy cdp enumerator data and unlock list
                    640:  */
                    641: static void cdp_data_destroy(cdp_data_t *data)
                    642: {
                    643:        data->this->lock->unlock(data->this->lock);
                    644:        free(data);
                    645: }
                    646: 
                    647: /**
                    648:  * inner enumerator constructor for CDP URIs
                    649:  */
                    650: static enumerator_t *create_inner_cdp(authority_t *authority, cdp_data_t *data)
                    651: {
                    652:        public_key_t *public;
                    653:        enumerator_t *enumerator = NULL;
                    654:        linked_list_t *list;
                    655: 
                    656:        if (data->type == CERT_X509_OCSP_RESPONSE)
                    657:        {
                    658:                list = authority->ocsp_uris;
                    659:        }
                    660:        else
                    661:        {
                    662:                list = authority->crl_uris;
                    663:        }
                    664: 
                    665:        public = authority->cert->get_public_key(authority->cert);
                    666:        if (public)
                    667:        {
                    668:                if (!data->id)
                    669:                {
                    670:                        enumerator = list->create_enumerator(list);
                    671:                }
                    672:                else
                    673:                {
                    674:                        if (public->has_fingerprint(public, data->id->get_encoding(data->id)))
                    675:                        {
                    676:                                enumerator = list->create_enumerator(list);
                    677:                        }
                    678:                }
                    679:                public->destroy(public);
                    680:        }
                    681:        return enumerator;
                    682: }
                    683: 
                    684: /**
                    685:  * inner enumerator constructor for "Hash and URL"
                    686:  */
                    687: static enumerator_t *create_inner_cdp_hashandurl(authority_t *authority,
                    688:                                                                                                 cdp_data_t *data)
                    689: {
                    690:        enumerator_t *enumerator = NULL;
                    691: 
                    692:        if (!data->id || !authority->cert_uri_base)
                    693:        {
                    694:                return NULL;
                    695:        }
                    696: 
                    697:        if (authority->cert->has_subject(authority->cert, data->id) != ID_MATCH_NONE)
                    698:        {
                    699:                enumerator = enumerator_create_single(strdup(authority->cert_uri_base),
                    700:                                                                                          free);
                    701:        }
                    702:        return enumerator;
                    703: }
                    704: 
                    705: METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
                    706:        private_vici_authority_t *this, certificate_type_t type,
                    707:        identification_t *id)
                    708: {
                    709:        cdp_data_t *data;
                    710: 
                    711:        switch (type)
                    712:        {       /* we serve CRLs, OCSP responders and URLs for "Hash and URL" */
                    713:                case CERT_X509:
                    714:                case CERT_X509_CRL:
                    715:                case CERT_X509_OCSP_RESPONSE:
                    716:                case CERT_ANY:
                    717:                        break;
                    718:                default:
                    719:                        return NULL;
                    720:        }
                    721:        data = malloc_thing(cdp_data_t);
                    722:        data->this = this;
                    723:        data->type = type;
                    724:        data->id = id;
                    725: 
                    726:        this->lock->read_lock(this->lock);
                    727: 
                    728:        return enumerator_create_nested(
                    729:                        this->authorities->create_enumerator(this->authorities),
                    730:                        (type == CERT_X509) ? (void*)create_inner_cdp_hashandurl :
                    731:                        (void*)create_inner_cdp, data, (void*)cdp_data_destroy);
                    732: }
                    733: 
                    734: METHOD(vici_authority_t, destroy, void,
                    735:        private_vici_authority_t *this)
                    736: {
                    737:        manage_commands(this, FALSE);
                    738: 
                    739:        this->authorities->destroy_function(this->authorities,
                    740:                                                                           (void*)authority_destroy);
                    741:        this->lock->destroy(this->lock);
                    742:        free(this);
                    743: }
                    744: 
                    745: /**
                    746:  * See header
                    747:  */
                    748: vici_authority_t *vici_authority_create(vici_dispatcher_t *dispatcher,
                    749:                                                                                vici_cred_t *cred)
                    750: {
                    751:        private_vici_authority_t *this;
                    752: 
                    753:        INIT(this,
                    754:                .public = {
                    755:                        .set = {
                    756:                                .create_private_enumerator = (void*)return_null,
                    757:                                .create_cert_enumerator = (void*)return_null,
                    758:                                .create_shared_enumerator = (void*)return_null,
                    759:                                .create_cdp_enumerator = _create_cdp_enumerator,
                    760:                                .cache_cert = (void*)nop,
                    761:                        },
                    762:                        .destroy = _destroy,
                    763:                },
                    764:                .dispatcher = dispatcher,
                    765:                .cred = cred,
                    766:                .authorities = linked_list_create(),
                    767:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                    768:        );
                    769: 
                    770:        manage_commands(this, TRUE);
                    771: 
                    772:        return &this->public;
                    773: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>