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>