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>