Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_authority.c, revision 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>