Return to dnscert_cred.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / dnscert |
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: }