Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_cred.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2015-2016 Andreas Steffen
        !             3:  * Copyright (C) 2016-2017 Tobias Brunner
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
        !             6:  * Copyright (C) 2014 Martin Willi
        !             7:  * Copyright (C) 2014 revosec AG
        !             8:  *
        !             9:  *
        !            10:  * This program is free software; you can redistribute it and/or modify it
        !            11:  * under the terms of the GNU General Public License as published by the
        !            12:  * Free Software Foundation; either version 2 of the License, or (at your
        !            13:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            14:  *
        !            15:  * This program is distributed in the hope that it will be useful, but
        !            16:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            17:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            18:  * for more details.
        !            19:  */
        !            20: 
        !            21: #include "vici_cred.h"
        !            22: #include "vici_builder.h"
        !            23: #include "vici_cert_info.h"
        !            24: 
        !            25: #include <credentials/sets/mem_cred.h>
        !            26: #include <credentials/certificates/ac.h>
        !            27: #include <credentials/certificates/crl.h>
        !            28: #include <credentials/certificates/x509.h>
        !            29: 
        !            30: #include <errno.h>
        !            31: 
        !            32: typedef struct private_vici_cred_t private_vici_cred_t;
        !            33: 
        !            34: /**
        !            35:  * Directory for saved X.509 CRLs
        !            36:  */
        !            37: #define CRL_DIR SWANCTLDIR "/x509crl"
        !            38: 
        !            39: /**
        !            40:  * Private data of an vici_cred_t object.
        !            41:  */
        !            42: struct private_vici_cred_t {
        !            43: 
        !            44:        /**
        !            45:         * Public vici_cred_t interface.
        !            46:         */
        !            47:        vici_cred_t public;
        !            48: 
        !            49:        /**
        !            50:         * Dispatcher
        !            51:         */
        !            52:        vici_dispatcher_t *dispatcher;
        !            53: 
        !            54:        /**
        !            55:         * credentials
        !            56:         */
        !            57:        mem_cred_t *creds;
        !            58: 
        !            59:        /**
        !            60:         * separate credential set for token PINs
        !            61:         */
        !            62:        mem_cred_t *pins;
        !            63: 
        !            64:        /**
        !            65:         * cache CRLs to disk?
        !            66:         */
        !            67:        bool cachecrl;
        !            68: 
        !            69: };
        !            70: 
        !            71: METHOD(credential_set_t, cache_cert, void,
        !            72:        private_vici_cred_t *this, certificate_t *cert)
        !            73: {
        !            74:        if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
        !            75:        {
        !            76:                /* CRLs get written to /etc/swanctl/x509crl/<authkeyId>.crl */
        !            77:                crl_t *crl = (crl_t*)cert;
        !            78: 
        !            79:                cert->get_ref(cert);
        !            80:                if (this->creds->add_crl(this->creds, crl))
        !            81:                {
        !            82:                        char buf[BUF_LEN];
        !            83:                        chunk_t chunk, hex;
        !            84:                        bool is_delta_crl;
        !            85: 
        !            86:                        is_delta_crl = crl->is_delta_crl(crl, NULL);
        !            87:                        chunk = crl->get_authKeyIdentifier(crl);
        !            88:                        hex = chunk_to_hex(chunk, NULL, FALSE);
        !            89:                        snprintf(buf, sizeof(buf), "%s/%s%s.crl", CRL_DIR, hex.ptr,
        !            90:                                                                                is_delta_crl ? "_delta" : "");
        !            91:                        free(hex.ptr);
        !            92: 
        !            93:                        if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk))
        !            94:                        {
        !            95:                                if (chunk_write(chunk, buf, 022, TRUE))
        !            96:                                {
        !            97:                                        DBG1(DBG_CFG, "  written crl file '%s' (%d bytes)",
        !            98:                                                 buf, chunk.len);
        !            99:                                }
        !           100:                                else
        !           101:                                {
        !           102:                                        DBG1(DBG_CFG, "  writing crl file '%s' failed: %s",
        !           103:                                                 buf, strerror(errno));
        !           104:                                }
        !           105:                                free(chunk.ptr);
        !           106:                        }
        !           107:                }
        !           108:        }
        !           109: }
        !           110: 
        !           111: /**
        !           112:  * Create a (error) reply message
        !           113:  */
        !           114: static vici_message_t* create_reply(char *fmt, ...)
        !           115: {
        !           116:        vici_builder_t *builder;
        !           117:        va_list args;
        !           118: 
        !           119:        builder = vici_builder_create();
        !           120:        builder->add_kv(builder, "success", fmt ? "no" : "yes");
        !           121:        if (fmt)
        !           122:        {
        !           123:                va_start(args, fmt);
        !           124:                builder->vadd_kv(builder, "errmsg", fmt, args);
        !           125:                va_end(args);
        !           126:        }
        !           127:        return builder->finalize(builder);
        !           128: }
        !           129: 
        !           130: CALLBACK(load_cert, vici_message_t*,
        !           131:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           132: {
        !           133:        certificate_t *cert;
        !           134:        certificate_type_t type;
        !           135:        x509_flag_t ext_flag, flag = X509_NONE;
        !           136:        x509_t *x509;
        !           137:        chunk_t data;
        !           138:        bool trusted = TRUE;
        !           139:        char *str;
        !           140: 
        !           141:        str = message->get_str(message, NULL, "type");
        !           142:        if (!str)
        !           143:        {
        !           144:                return create_reply("certificate type missing");
        !           145:        }
        !           146:        if (enum_from_name(certificate_type_names, str, &type))
        !           147:        {
        !           148:                if (type == CERT_X509)
        !           149:                {
        !           150:                        str = message->get_str(message, "NONE", "flag");
        !           151:                        if (!enum_from_name(x509_flag_names, str, &flag))
        !           152:                        {
        !           153:                                return create_reply("invalid certificate flag '%s'", str);
        !           154:                        }
        !           155:                }
        !           156:        }
        !           157:        else if (!vici_cert_info_from_str(str, &type, &flag))
        !           158:        {
        !           159:                return create_reply("invalid certificate type '%s'", str);
        !           160:        }
        !           161: 
        !           162:        data = message->get_value(message, chunk_empty, "data");
        !           163:        if (!data.len)
        !           164:        {
        !           165:                return create_reply("certificate data missing");
        !           166:        }
        !           167: 
        !           168:        /* do not set CA flag externally */
        !           169:        ext_flag = (flag & X509_CA) ? X509_NONE : flag;
        !           170: 
        !           171:        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
        !           172:                                                          BUILD_BLOB_PEM, data,
        !           173:                                                          BUILD_X509_FLAG, ext_flag,
        !           174:                                                          BUILD_END);
        !           175:        if (!cert)
        !           176:        {
        !           177:                return create_reply("parsing %N certificate failed",
        !           178:                                                        certificate_type_names, type);
        !           179:        }
        !           180:        DBG1(DBG_CFG, "loaded certificate '%Y'", cert->get_subject(cert));
        !           181: 
        !           182:        /* check if CA certificate has CA basic constraint set */
        !           183:        if (flag & X509_CA)
        !           184:        {
        !           185:                char err_msg[] = "ca certificate lacks CA basic constraint, rejected";
        !           186:                x509 = (x509_t*)cert;
        !           187: 
        !           188:                if (!(x509->get_flags(x509) & X509_CA))
        !           189:                {
        !           190:                        cert->destroy(cert);
        !           191:                        DBG1(DBG_CFG, "  %s", err_msg);
        !           192:                        return create_reply(err_msg);
        !           193:                }
        !           194:        }
        !           195:        if (type == CERT_X509_CRL)
        !           196:        {
        !           197:                this->creds->add_crl(this->creds, (crl_t*)cert);
        !           198:        }
        !           199:        else
        !           200:        {
        !           201:                this->creds->add_cert(this->creds, trusted, cert);
        !           202:        }
        !           203:        return create_reply(NULL);
        !           204: }
        !           205: 
        !           206: CALLBACK(load_key, vici_message_t*,
        !           207:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           208: {
        !           209:        vici_builder_t *builder;
        !           210:        key_type_t type;
        !           211:        private_key_t *key;
        !           212:        chunk_t data, fp;
        !           213:        char *str;
        !           214: 
        !           215:        str = message->get_str(message, NULL, "type");
        !           216:        if (!str)
        !           217:        {
        !           218:                return create_reply("key type missing");
        !           219:        }
        !           220:        if (strcaseeq(str, "any"))
        !           221:        {
        !           222:                type = KEY_ANY;
        !           223:        }
        !           224:        else if (strcaseeq(str, "rsa"))
        !           225:        {
        !           226:                type = KEY_RSA;
        !           227:        }
        !           228:        else if (strcaseeq(str, "ecdsa"))
        !           229:        {
        !           230:                type = KEY_ECDSA;
        !           231:        }
        !           232:        else if (strcaseeq(str, "bliss"))
        !           233:        {
        !           234:                type = KEY_BLISS;
        !           235:        }
        !           236:        else
        !           237:        {
        !           238:                return create_reply("invalid key type: %s", str);
        !           239:        }
        !           240:        data = message->get_value(message, chunk_empty, "data");
        !           241:        if (!data.len)
        !           242:        {
        !           243:                return create_reply("key data missing");
        !           244:        }
        !           245:        key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
        !           246:                                                         BUILD_BLOB_PEM, data, BUILD_END);
        !           247:        if (!key)
        !           248:        {
        !           249:                return create_reply("parsing %N private key failed",
        !           250:                                                        key_type_names, type);
        !           251:        }
        !           252:        if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp))
        !           253:        {
        !           254:                return create_reply("failed to get key id");
        !           255:        }
        !           256: 
        !           257:        DBG1(DBG_CFG, "loaded %N private key", key_type_names, type);
        !           258: 
        !           259:        builder = vici_builder_create();
        !           260:        builder->add_kv(builder, "success", "yes");
        !           261:        builder->add_kv(builder, "id", "%+B", &fp);
        !           262:        this->creds->add_key(this->creds, key);
        !           263: 
        !           264:        return builder->finalize(builder);
        !           265: }
        !           266: 
        !           267: CALLBACK(unload_key, vici_message_t*,
        !           268:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           269: {
        !           270:        chunk_t keyid;
        !           271:        char buf[BUF_LEN], *hex, *msg = NULL;
        !           272: 
        !           273:        hex = message->get_str(message, NULL, "id");
        !           274:        if (!hex)
        !           275:        {
        !           276:                return create_reply("key id missing");
        !           277:        }
        !           278:        keyid = chunk_from_hex(chunk_from_str(hex), NULL);
        !           279:        snprintf(buf, sizeof(buf), "%+B", &keyid);
        !           280:        DBG1(DBG_CFG, "unloaded private key with id %s", buf);
        !           281:        if (this->creds->remove_key(this->creds, keyid))
        !           282:        {       /* also remove any potential PIN associated with this id */
        !           283:                this->pins->remove_shared_unique(this->pins, buf);
        !           284:        }
        !           285:        else
        !           286:        {
        !           287:                msg = "key not found";
        !           288:        }
        !           289:        chunk_free(&keyid);
        !           290:        return create_reply(msg);
        !           291: }
        !           292: 
        !           293: CALLBACK(get_keys, vici_message_t*,
        !           294:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           295: {
        !           296:        vici_builder_t *builder;
        !           297:        enumerator_t *enumerator;
        !           298:        private_key_t *private;
        !           299:        chunk_t keyid;
        !           300: 
        !           301:        builder = vici_builder_create();
        !           302:        builder->begin_list(builder, "keys");
        !           303: 
        !           304:        enumerator = this->creds->set.create_private_enumerator(&this->creds->set,
        !           305:                                                                                                                        KEY_ANY, NULL);
        !           306:        while (enumerator->enumerate(enumerator, &private))
        !           307:        {
        !           308:                if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &keyid))
        !           309:                {
        !           310:                        builder->add_li(builder, "%+B", &keyid);
        !           311:                }
        !           312:        }
        !           313:        enumerator->destroy(enumerator);
        !           314: 
        !           315:        builder->end_list(builder);
        !           316:        return builder->finalize(builder);
        !           317: }
        !           318: 
        !           319: CALLBACK(load_token, vici_message_t*,
        !           320:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           321: {
        !           322:        vici_builder_t *builder;
        !           323:        private_key_t *key;
        !           324:        shared_key_t *shared = NULL;
        !           325:        identification_t *owner;
        !           326:        mem_cred_t *set = NULL;
        !           327:        chunk_t handle, fp;
        !           328:        char buf[BUF_LEN], *hex, *module, *pin, *unique = NULL;
        !           329:        int slot;
        !           330: 
        !           331:        hex = message->get_str(message, NULL, "handle");
        !           332:        if (!hex)
        !           333:        {
        !           334:                return create_reply("keyid missing");
        !           335:        }
        !           336:        handle = chunk_from_hex(chunk_from_str(hex), NULL);
        !           337:        slot = message->get_int(message, -1, "slot");
        !           338:        module = message->get_str(message, NULL, "module");
        !           339:        pin = message->get_str(message, NULL, "pin");
        !           340: 
        !           341:        if (pin)
        !           342:        {       /* provide the pin in a temporary credential set to access the key */
        !           343:                shared = shared_key_create(SHARED_PIN, chunk_clone(chunk_from_str(pin)));
        !           344:                owner = identification_create_from_encoding(ID_KEY_ID, handle);
        !           345:                set = mem_cred_create();
        !           346:                set->add_shared(set, shared->get_ref(shared), owner, NULL);
        !           347:                lib->credmgr->add_local_set(lib->credmgr, &set->set, FALSE);
        !           348:        }
        !           349:        if (slot >= 0)
        !           350:        {
        !           351:                key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
        !           352:                                                BUILD_PKCS11_KEYID, handle,
        !           353:                                                BUILD_PKCS11_SLOT, slot,
        !           354:                                                module ? BUILD_PKCS11_MODULE : BUILD_END, module,
        !           355:                                                BUILD_END);
        !           356:        }
        !           357:        else
        !           358:        {
        !           359:                key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
        !           360:                                                BUILD_PKCS11_KEYID, handle,
        !           361:                                                module ? BUILD_PKCS11_MODULE : BUILD_END, module,
        !           362:                                                BUILD_END);
        !           363:        }
        !           364:        if (set)
        !           365:        {
        !           366:                lib->credmgr->remove_local_set(lib->credmgr, &set->set);
        !           367:                set->destroy(set);
        !           368:        }
        !           369:        if (!key)
        !           370:        {
        !           371:                chunk_free(&handle);
        !           372:                DESTROY_IF(shared);
        !           373:                return create_reply("loading private key from token failed");
        !           374:        }
        !           375:        builder = vici_builder_create();
        !           376:        builder->add_kv(builder, "success", "yes");
        !           377:        if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp))
        !           378:        {
        !           379:                snprintf(buf, sizeof(buf), "%+B", &fp);
        !           380:                builder->add_kv(builder, "id", "%s", buf);
        !           381:                unique = buf;
        !           382:        }
        !           383:        if (shared && unique)
        !           384:        {       /* use the handle as owner, but the key identifier as unique ID */
        !           385:                owner = identification_create_from_encoding(ID_KEY_ID, handle);
        !           386:                this->pins->add_shared_unique(this->pins, unique, shared,
        !           387:                                                                        linked_list_create_with_items(owner, NULL));
        !           388:        }
        !           389:        else
        !           390:        {
        !           391:                DESTROY_IF(shared);
        !           392:        }
        !           393:        DBG1(DBG_CFG, "loaded %N private key from token", key_type_names,
        !           394:                 key->get_type(key));
        !           395:        this->creds->add_key(this->creds, key);
        !           396:        chunk_free(&handle);
        !           397:        return builder->finalize(builder);
        !           398: }
        !           399: 
        !           400: CALLBACK(shared_owners, bool,
        !           401:        linked_list_t *owners, vici_message_t *message, char *name, chunk_t value)
        !           402: {
        !           403:        if (streq(name, "owners"))
        !           404:        {
        !           405:                char buf[256];
        !           406: 
        !           407:                if (!vici_stringify(value, buf, sizeof(buf)))
        !           408:                {
        !           409:                        return FALSE;
        !           410:                }
        !           411:                owners->insert_last(owners, identification_create_from_string(buf));
        !           412:        }
        !           413:        return TRUE;
        !           414: }
        !           415: 
        !           416: CALLBACK(load_shared, vici_message_t*,
        !           417:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           418: {
        !           419:        shared_key_type_t type;
        !           420:        linked_list_t *owners;
        !           421:        chunk_t data;
        !           422:        char *unique, *str, buf[512] = "";
        !           423:        enumerator_t *enumerator;
        !           424:        identification_t *owner;
        !           425:        int len;
        !           426: 
        !           427:        unique = message->get_str(message, NULL, "id");
        !           428:        str = message->get_str(message, NULL, "type");
        !           429:        if (!str)
        !           430:        {
        !           431:                return create_reply("shared key type missing");
        !           432:        }
        !           433:        if (strcaseeq(str, "ike"))
        !           434:        {
        !           435:                type = SHARED_IKE;
        !           436:        }
        !           437:        else if (strcaseeq(str, "eap") || strcaseeq(str, "xauth"))
        !           438:        {
        !           439:                type = SHARED_EAP;
        !           440:        }
        !           441:        else if (strcaseeq(str, "ntlm"))
        !           442:        {
        !           443:                type = SHARED_NT_HASH;
        !           444:        }
        !           445:        else if (strcaseeq(str, "ppk"))
        !           446:        {
        !           447:                type = SHARED_PPK;
        !           448:        }
        !           449:        else
        !           450:        {
        !           451:                return create_reply("invalid shared key type: %s", str);
        !           452:        }
        !           453:        data = message->get_value(message, chunk_empty, "data");
        !           454:        if (!data.len)
        !           455:        {
        !           456:                return create_reply("shared key data missing");
        !           457:        }
        !           458: 
        !           459:        owners = linked_list_create();
        !           460:        if (!message->parse(message, NULL, NULL, NULL, shared_owners, owners))
        !           461:        {
        !           462:                owners->destroy_offset(owners, offsetof(identification_t, destroy));
        !           463:                return create_reply("parsing shared key owners failed");
        !           464:        }
        !           465:        if (owners->get_count(owners) == 0)
        !           466:        {
        !           467:                owners->insert_last(owners, identification_create_from_string("%any"));
        !           468:        }
        !           469: 
        !           470:        enumerator = owners->create_enumerator(owners);
        !           471:        while (enumerator->enumerate(enumerator, &owner))
        !           472:        {
        !           473:                len = strlen(buf);
        !           474:                if (len < sizeof(buf))
        !           475:                {
        !           476:                        snprintf(buf + len, sizeof(buf) - len, "%s'%Y'",
        !           477:                                         len ? ", " : "", owner);
        !           478:                }
        !           479:        }
        !           480:        enumerator->destroy(enumerator);
        !           481: 
        !           482:        if (unique)
        !           483:        {
        !           484:                DBG1(DBG_CFG, "loaded %N shared key with id '%s' for: %s",
        !           485:                         shared_key_type_names, type, unique, buf);
        !           486:        }
        !           487:        else
        !           488:        {
        !           489:                DBG1(DBG_CFG, "loaded %N shared key for: %s",
        !           490:                         shared_key_type_names, type, buf);
        !           491:        }
        !           492: 
        !           493:        this->creds->add_shared_unique(this->creds, unique,
        !           494:                                                shared_key_create(type, chunk_clone(data)), owners);
        !           495: 
        !           496:        return create_reply(NULL);
        !           497: }
        !           498: 
        !           499: CALLBACK(unload_shared, vici_message_t*,
        !           500:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           501: {
        !           502:        char *unique;
        !           503: 
        !           504:        unique = message->get_str(message, NULL, "id");
        !           505:        if (!unique)
        !           506:        {
        !           507:                return create_reply("unique identifier missing");
        !           508:        }
        !           509:        DBG1(DBG_CFG, "unloaded shared key with id '%s'", unique);
        !           510:        this->creds->remove_shared_unique(this->creds, unique);
        !           511:        return create_reply(NULL);
        !           512: }
        !           513: 
        !           514: CALLBACK(get_shared, vici_message_t*,
        !           515:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           516: {
        !           517:        vici_builder_t *builder;
        !           518:        enumerator_t *enumerator;
        !           519:        char *unique;
        !           520: 
        !           521:        builder = vici_builder_create();
        !           522:        builder->begin_list(builder, "keys");
        !           523: 
        !           524:        enumerator = this->creds->create_unique_shared_enumerator(this->creds);
        !           525:        while (enumerator->enumerate(enumerator, &unique))
        !           526:        {
        !           527:                builder->add_li(builder, "%s", unique);
        !           528:        }
        !           529:        enumerator->destroy(enumerator);
        !           530: 
        !           531:        builder->end_list(builder);
        !           532:        return builder->finalize(builder);
        !           533: }
        !           534: 
        !           535: CALLBACK(clear_creds, vici_message_t*,
        !           536:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           537: {
        !           538:        this->creds->clear(this->creds);
        !           539:        lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
        !           540: 
        !           541:        return create_reply(NULL);
        !           542: }
        !           543: 
        !           544: CALLBACK(flush_certs, vici_message_t*,
        !           545:        private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
        !           546: {
        !           547:        certificate_type_t type = CERT_ANY;
        !           548:        x509_flag_t flag = X509_NONE;
        !           549:        char *str;
        !           550: 
        !           551:        str = message->get_str(message, NULL, "type");
        !           552:        if (str && !enum_from_name(certificate_type_names, str, &type) &&
        !           553:                           !vici_cert_info_from_str(str, &type, &flag))
        !           554:        {
        !           555:                return create_reply("invalid certificate type '%s'", str);
        !           556:        }
        !           557:        lib->credmgr->flush_cache(lib->credmgr, type);
        !           558: 
        !           559:        return create_reply(NULL);
        !           560: }
        !           561: 
        !           562: static void manage_command(private_vici_cred_t *this,
        !           563:                                                   char *name, vici_command_cb_t cb, bool reg)
        !           564: {
        !           565:        this->dispatcher->manage_command(this->dispatcher, name,
        !           566:                                                                         reg ? cb : NULL, this);
        !           567: }
        !           568: 
        !           569: /**
        !           570:  * (Un-)register dispatcher functions
        !           571:  */
        !           572: static void manage_commands(private_vici_cred_t *this, bool reg)
        !           573: {
        !           574:        manage_command(this, "clear-creds", clear_creds, reg);
        !           575:        manage_command(this, "flush-certs", flush_certs, reg);
        !           576:        manage_command(this, "load-cert", load_cert, reg);
        !           577:        manage_command(this, "load-key", load_key, reg);
        !           578:        manage_command(this, "unload-key", unload_key, reg);
        !           579:        manage_command(this, "get-keys", get_keys, reg);
        !           580:        manage_command(this, "load-token", load_token, reg);
        !           581:        manage_command(this, "load-shared", load_shared, reg);
        !           582:        manage_command(this, "unload-shared", unload_shared, reg);
        !           583:        manage_command(this, "get-shared", get_shared, reg);
        !           584: }
        !           585: 
        !           586: METHOD(vici_cred_t, add_cert, certificate_t*,
        !           587:        private_vici_cred_t *this, certificate_t *cert)
        !           588: {
        !           589:        return this->creds->add_cert_ref(this->creds, TRUE, cert);
        !           590: }
        !           591: 
        !           592: METHOD(vici_cred_t, destroy, void,
        !           593:        private_vici_cred_t *this)
        !           594: {
        !           595:        manage_commands(this, FALSE);
        !           596: 
        !           597:        lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
        !           598:        this->creds->destroy(this->creds);
        !           599:        lib->credmgr->remove_set(lib->credmgr, &this->pins->set);
        !           600:        this->pins->destroy(this->pins);
        !           601:        free(this);
        !           602: }
        !           603: 
        !           604: /**
        !           605:  * See header
        !           606:  */
        !           607: vici_cred_t *vici_cred_create(vici_dispatcher_t *dispatcher)
        !           608: {
        !           609:        private_vici_cred_t *this;
        !           610: 
        !           611:        INIT(this,
        !           612:                .public = {
        !           613:                        .set = {
        !           614:                                .create_private_enumerator = (void*)return_null,
        !           615:                                .create_cert_enumerator = (void*)return_null,
        !           616:                                .create_shared_enumerator = (void*)return_null,
        !           617:                                .create_cdp_enumerator = (void*)return_null,
        !           618:                                .cache_cert = (void*)_cache_cert,
        !           619:                        },
        !           620:                        .add_cert = _add_cert,
        !           621:                        .destroy = _destroy,
        !           622:                },
        !           623:                .dispatcher = dispatcher,
        !           624:                .creds = mem_cred_create(),
        !           625:                .pins = mem_cred_create(),
        !           626:        );
        !           627: 
        !           628:        if (lib->settings->get_bool(lib->settings, "%s.cache_crls", FALSE, lib->ns))
        !           629:        {
        !           630:                this->cachecrl = TRUE;
        !           631:                DBG1(DBG_CFG, "crl caching to %s enabled", CRL_DIR);
        !           632:        }
        !           633:        lib->credmgr->add_set(lib->credmgr, &this->creds->set);
        !           634:        lib->credmgr->add_set(lib->credmgr, &this->pins->set);
        !           635: 
        !           636:        manage_commands(this, TRUE);
        !           637: 
        !           638:        return &this->public;
        !           639: }

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