Annotation of embedaddon/strongswan/src/libcharon/plugins/dnscert/dnscert_cred.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2013 Tobias Brunner
        !             3:  * Copyright (C) 2012 Reto Guadagnini
        !             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:  * Copyright (C) 2013 Ruslan Marchenko
        !            18:  *
        !            19:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !            20:  * of this software and associated documentation files (the "Software"), to deal
        !            21:  * in the Software without restriction, including without limitation the rights
        !            22:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            23:  * copies of the Software, and to permit persons to whom the Software is
        !            24:  * furnished to do so, subject to the following conditions:
        !            25:  *
        !            26:  * The above copyright notice and this permission notice shall be included in
        !            27:  * all copies or substantial portions of the Software.
        !            28:  *
        !            29:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            30:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            31:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        !            32:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            33:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            34:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            35:  * THE SOFTWARE.
        !            36:  */
        !            37: 
        !            38: #define _GNU_SOURCE
        !            39: #include <stdio.h>
        !            40: #include <string.h>
        !            41: 
        !            42: #include "dnscert_cred.h"
        !            43: #include "dnscert.h"
        !            44: 
        !            45: typedef struct private_dnscert_cred_t private_dnscert_cred_t;
        !            46: 
        !            47: /**
        !            48:  * Private data of an dnscert_cred_t object
        !            49:  */
        !            50: struct private_dnscert_cred_t {
        !            51: 
        !            52:        /**
        !            53:         * Public part
        !            54:         */
        !            55:        dnscert_cred_t public;
        !            56: 
        !            57:        /**
        !            58:         * DNS resolver
        !            59:         */
        !            60:        resolver_t *res;
        !            61: };
        !            62: 
        !            63: /**
        !            64:  * enumerator over certificates
        !            65:  */
        !            66: typedef struct {
        !            67:        /** implements enumerator interface */
        !            68:        enumerator_t public;
        !            69:        /** inner enumerator (enumerates CERT resource records) */
        !            70:        enumerator_t *inner;
        !            71:        /** response of the DNS resolver which contains the CERTs */
        !            72:        resolver_response_t *response;
        !            73:        /** most recently enumerated certificate */
        !            74:        certificate_t *cert;
        !            75: } cert_enumerator_t;
        !            76: 
        !            77: METHOD(enumerator_t, cert_enumerator_enumerate, bool,
        !            78:        cert_enumerator_t *this, va_list args)
        !            79: {
        !            80:        certificate_t **cert;
        !            81:        dnscert_t *cur_crt;
        !            82:        rr_t *cur_rr;
        !            83:        chunk_t certificate;
        !            84: 
        !            85:        VA_ARGS_VGET(args, cert);
        !            86: 
        !            87:        /* Get the next supported CERT using the inner enumerator. */
        !            88:        while (this->inner->enumerate(this->inner, &cur_rr))
        !            89:        {
        !            90:                cur_crt = dnscert_create_frm_rr(cur_rr);
        !            91: 
        !            92:                if (!cur_crt)
        !            93:                {
        !            94:                        DBG1(DBG_CFG, "  failed to parse CERT RR, skipping");
        !            95:                        continue;
        !            96:                }
        !            97: 
        !            98:                if (cur_crt->get_cert_type(cur_crt) != DNSCERT_TYPE_PKIX &&
        !            99:                        cur_crt->get_cert_type(cur_crt) != DNSCERT_TYPE_PGP)
        !           100:                {
        !           101:                        DBG1(DBG_CFG, "  unsupported CERT type [%d], skipping",
        !           102:                                 cur_crt->get_cert_type(cur_crt));
        !           103:                        cur_crt->destroy(cur_crt);
        !           104:                        continue;
        !           105:                }
        !           106:                /* Try to parse PEM certificate container. Both x509 and PGP should
        !           107:                 * presumably come as PEM encoded certs. */
        !           108:                certificate = cur_crt->get_certificate(cur_crt);
        !           109:                DESTROY_IF(this->cert);
        !           110:                this->cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_ANY,
        !           111:                                                                                BUILD_BLOB_PEM, certificate,
        !           112:                                                                                BUILD_END);
        !           113:                cur_crt->destroy(cur_crt);
        !           114:                if (!this->cert)
        !           115:                {
        !           116:                        DBG1(DBG_CFG, "  unable to parse certificate, skipping");
        !           117:                        continue;
        !           118:                }
        !           119:                *cert = this->cert;
        !           120:                return TRUE;
        !           121:        }
        !           122:        return FALSE;
        !           123: }
        !           124: 
        !           125: METHOD(enumerator_t, cert_enumerator_destroy, void,
        !           126:        cert_enumerator_t *this)
        !           127: {
        !           128:        DESTROY_IF(this->cert);
        !           129:        this->inner->destroy(this->inner);
        !           130:        this->response->destroy(this->response);
        !           131:        free(this);
        !           132: }
        !           133: 
        !           134: METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
        !           135:        private_dnscert_cred_t *this, certificate_type_t cert, key_type_t key,
        !           136:        identification_t *id, bool trusted)
        !           137: {
        !           138:        resolver_response_t *response;
        !           139:        cert_enumerator_t *e;
        !           140:        char *fqdn;
        !           141: 
        !           142:        if (!id || id->get_type(id) != ID_FQDN)
        !           143:        {
        !           144:                return enumerator_create_empty();
        !           145:        }
        !           146: 
        !           147:        /* query the DNS for the required CERT RRs */
        !           148:        if (asprintf(&fqdn, "%Y", id) <= 0)
        !           149:        {
        !           150:                DBG1(DBG_CFG, "failed to determine FQDN to retrieve CERT RRs");
        !           151:                return enumerator_create_empty();
        !           152:        }
        !           153: 
        !           154:        DBG1(DBG_CFG, "performing a DNS query for CERT RRs of '%s'", fqdn);
        !           155:        response = this->res->query(this->res, fqdn, RR_CLASS_IN, RR_TYPE_CERT);
        !           156:        if (!response)
        !           157:        {
        !           158:                DBG1(DBG_CFG, "  query for CERT RRs failed");
        !           159:                free(fqdn);
        !           160:                return enumerator_create_empty();
        !           161:        }
        !           162:        free(fqdn);
        !           163: 
        !           164:        if (!response->has_data(response) ||
        !           165:                !response->query_name_exist(response))
        !           166:        {
        !           167:                DBG1(DBG_CFG, "  unable to retrieve CERT RRs from the DNS");
        !           168:                response->destroy(response);
        !           169:                return enumerator_create_empty();
        !           170:        }
        !           171: 
        !           172:        if (response->get_security_state(response) != SECURE)
        !           173:        {
        !           174:                DBG1(DBG_CFG, "  DNSSEC state of CERT RRs is not secure");
        !           175:                response->destroy(response);
        !           176:                return enumerator_create_empty();
        !           177:        }
        !           178: 
        !           179:        INIT(e,
        !           180:                .public = {
        !           181:                        .enumerate = enumerator_enumerate_default,
        !           182:                        .venumerate = _cert_enumerator_enumerate,
        !           183:                        .destroy = _cert_enumerator_destroy,
        !           184:                },
        !           185:                .inner = response->get_rr_set(response)->create_rr_enumerator(
        !           186:                                                                          response->get_rr_set(response)),
        !           187:                .response = response
        !           188:        );
        !           189:        return &e->public;
        !           190: }
        !           191: 
        !           192: METHOD(dnscert_cred_t, destroy, void,
        !           193:        private_dnscert_cred_t *this)
        !           194: {
        !           195:        this->res->destroy(this->res);
        !           196:        free(this);
        !           197: }
        !           198: 
        !           199: /**
        !           200:  * Described in header.
        !           201:  */
        !           202: dnscert_cred_t *dnscert_cred_create(resolver_t *res)
        !           203: {
        !           204:        private_dnscert_cred_t *this;
        !           205: 
        !           206:        INIT(this,
        !           207:                .public = {
        !           208:                        .set = {
        !           209:                                .create_private_enumerator = (void*)return_null,
        !           210:                                .create_cert_enumerator = _create_cert_enumerator,
        !           211:                                .create_shared_enumerator = (void*)return_null,
        !           212:                                .create_cdp_enumerator = (void*)return_null,
        !           213:                                .cache_cert = (void*)nop,
        !           214:                        },
        !           215:                        .destroy = _destroy,
        !           216:                },
        !           217:                .res = res,
        !           218:        );
        !           219: 
        !           220:        return &this->public;
        !           221: }

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