Moved data structures to new collections subfolder
[strongswan.git] / src / libcharon / plugins / medcli / medcli_creds.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "medcli_creds.h"
17
18 #include <daemon.h>
19 #include <library.h>
20 #include <collections/enumerator.h>
21
22 typedef struct private_medcli_creds_t private_medcli_creds_t;
23
24 /**
25 * Private data of an medcli_creds_t object
26 */
27 struct private_medcli_creds_t {
28
29 /**
30 * Public part
31 */
32 medcli_creds_t public;
33
34 /**
35 * underlying database handle
36 */
37 database_t *db;
38 };
39
40 /**
41 * enumerator over private keys
42 */
43 typedef struct {
44 /** implements enumerator */
45 enumerator_t public;
46 /** inner SQL enumerator */
47 enumerator_t *inner;
48 /** currently enumerated private key */
49 private_key_t *current;
50 } private_enumerator_t;
51
52 METHOD(enumerator_t, private_enumerator_enumerate, bool,
53 private_enumerator_t *this, private_key_t **key)
54 {
55 chunk_t chunk;
56
57 DESTROY_IF(this->current);
58 while (this->inner->enumerate(this->inner, &chunk))
59 {
60 this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
61 BUILD_BLOB_ASN1_DER, chunk,
62 BUILD_END);
63 if (this->current)
64 {
65 *key = this->current;
66 return TRUE;
67 }
68 }
69 this->current = NULL;
70 return FALSE;
71 }
72
73 METHOD(enumerator_t, private_enumerator_destroy, void,
74 private_enumerator_t *this)
75 {
76 DESTROY_IF(this->current);
77 this->inner->destroy(this->inner);
78 free(this);
79 }
80
81 METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
82 private_medcli_creds_t *this, key_type_t type, identification_t *id)
83 {
84 private_enumerator_t *e;
85
86 if ((type != KEY_RSA && type != KEY_ANY) ||
87 id == NULL || id->get_type(id) != ID_KEY_ID)
88 {
89 DBG1(DBG_CFG, "%N - %Y", key_type_names, type, id);
90 return NULL;
91 }
92
93 INIT(e,
94 .public = {
95 .enumerate = (void*)_private_enumerator_enumerate,
96 .destroy = _private_enumerator_destroy,
97 },
98 );
99 e->inner = this->db->query(this->db,
100 "SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?",
101 DB_BLOB, id->get_encoding(id),
102 DB_BLOB);
103 if (!e->inner)
104 {
105 free(e);
106 return NULL;
107 }
108 return &e->public;
109 }
110
111 /**
112 * enumerator over certificates
113 */
114 typedef struct {
115 /** implements enumerator */
116 enumerator_t public;
117 /** inner SQL enumerator */
118 enumerator_t *inner;
119 /** currently enumerated cert */
120 certificate_t *current;
121 /** type of requested key */
122 key_type_t type;
123 } cert_enumerator_t;
124
125 METHOD(enumerator_t, cert_enumerator_enumerate, bool,
126 cert_enumerator_t *this, certificate_t **cert)
127 {
128 public_key_t *public;
129 chunk_t chunk;
130
131 DESTROY_IF(this->current);
132 while (this->inner->enumerate(this->inner, &chunk))
133 {
134 public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
135 BUILD_BLOB_ASN1_DER, chunk,
136 BUILD_END);
137 if (public)
138 {
139 if (this->type == KEY_ANY || this->type == public->get_type(public))
140 {
141 this->current = lib->creds->create(lib->creds,
142 CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
143 BUILD_PUBLIC_KEY, public, BUILD_END);
144 public->destroy(public);
145 if (this->current)
146 {
147 *cert = this->current;
148 return TRUE;
149 }
150 }
151 else
152 {
153 public->destroy(public);
154 }
155 }
156 }
157 this->current = NULL;
158 return FALSE;
159 }
160
161 METHOD(enumerator_t, cert_enumerator_destroy, void,
162 cert_enumerator_t *this)
163 {
164 DESTROY_IF(this->current);
165 this->inner->destroy(this->inner);
166 free(this);
167 }
168
169 METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
170 private_medcli_creds_t *this, certificate_type_t cert, key_type_t key,
171 identification_t *id, bool trusted)
172 {
173 cert_enumerator_t *e;
174
175 if ((cert != CERT_TRUSTED_PUBKEY && cert != CERT_ANY) ||
176 id == NULL || id->get_type(id) != ID_KEY_ID)
177 {
178 return NULL;
179 }
180
181 INIT(e,
182 .public = {
183 .enumerate = (void*)_cert_enumerator_enumerate,
184 .destroy = _cert_enumerator_destroy,
185 },
186 .type = key,
187 );
188 e->inner = this->db->query(this->db,
189 "SELECT PublicKey FROM ClientConfig WHERE KeyId = ? UNION "
190 "SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION "
191 "SELECT PublicKey FROM Connection WHERE KeyId = ?",
192 DB_BLOB, id->get_encoding(id),
193 DB_BLOB, id->get_encoding(id),
194 DB_BLOB, id->get_encoding(id),
195 DB_BLOB);
196 if (!e->inner)
197 {
198 free(e);
199 return NULL;
200 }
201 return &e->public;
202 }
203
204 METHOD(medcli_creds_t, destroy, void,
205 private_medcli_creds_t *this)
206 {
207 free(this);
208 }
209
210 /**
211 * Described in header.
212 */
213 medcli_creds_t *medcli_creds_create(database_t *db)
214 {
215 private_medcli_creds_t *this;
216
217 INIT(this,
218 .public = {
219 .set = {
220 .create_private_enumerator = _create_private_enumerator,
221 .create_cert_enumerator = _create_cert_enumerator,
222 .create_shared_enumerator = (void*)return_null,
223 .create_cdp_enumerator = (void*)return_null,
224 .cache_cert = (void*)nop,
225 },
226 .destroy = _destroy,
227 },
228 .db = db,
229 );
230
231 return &this->public;
232 }
233