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