2 * Copyright (C) 2010-2019 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
5 * Copyright (C) secunet Security Networks AG
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 typedef struct private_sql_cred_t private_sql_cred_t
;
27 * Private data of an sql_cred_t object
29 struct private_sql_cred_t
{
44 * enumerator over private keys
47 /** implements enumerator */
49 /** inner SQL enumerator */
51 /** currently enumerated private key */
52 private_key_t
*current
;
53 } private_enumerator_t
;
55 METHOD(enumerator_t
, private_enumerator_enumerate
, bool,
56 private_enumerator_t
*this, va_list args
)
62 VA_ARGS_VGET(args
, key
);
64 DESTROY_IF(this->current
);
65 while (this->inner
->enumerate(this->inner
, &type
, &blob
))
67 this->current
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, type
,
80 METHOD(enumerator_t
, private_enumerator_destroy
, void,
81 private_enumerator_t
*this)
83 DESTROY_IF(this->current
);
84 this->inner
->destroy(this->inner
);
88 METHOD(credential_set_t
, create_private_enumerator
, enumerator_t
*,
89 private_sql_cred_t
*this, key_type_t type
, identification_t
*id
)
91 private_enumerator_t
*e
;
95 .enumerate
= enumerator_enumerate_default
,
96 .venumerate
= _private_enumerator_enumerate
,
97 .destroy
= _private_enumerator_destroy
,
100 if (id
&& id
->get_type(id
) != ID_ANY
)
102 e
->inner
= this->db
->query(this->db
,
103 "SELECT p.type, p.data FROM private_keys AS p "
104 "JOIN private_key_identity AS pi ON p.id = pi.private_key "
105 "JOIN identities AS i ON pi.identity = i.id "
106 "WHERE i.type = ? AND i.data = ? AND (? OR p.type = ?)",
107 DB_INT
, id
->get_type(id
), DB_BLOB
, id
->get_encoding(id
),
108 DB_INT
, type
== KEY_ANY
, DB_INT
, type
,
113 e
->inner
= this->db
->query(this->db
,
114 "SELECT p.type, p.data FROM private_keys AS p "
115 "WHERE (? OR p.type = ?)",
116 DB_INT
, type
== KEY_ANY
, DB_INT
, type
,
129 * enumerator over certificates
132 /** implements enumerator */
134 /** inner SQL enumerator */
136 /** currently enumerated cert */
137 certificate_t
*current
;
140 METHOD(enumerator_t
, cert_enumerator_enumerate
, bool,
141 cert_enumerator_t
*this, va_list args
)
143 certificate_t
**cert
;
147 VA_ARGS_VGET(args
, cert
);
149 DESTROY_IF(this->current
);
150 while (this->inner
->enumerate(this->inner
, &type
, &blob
))
152 this->current
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, type
,
153 BUILD_BLOB_PEM
, blob
,
157 *cert
= this->current
;
161 this->current
= NULL
;
165 METHOD(enumerator_t
, cert_enumerator_destroy
, void,
166 cert_enumerator_t
*this)
168 DESTROY_IF(this->current
);
169 this->inner
->destroy(this->inner
);
173 METHOD(credential_set_t
, create_cert_enumerator
, enumerator_t
*,
174 private_sql_cred_t
*this, certificate_type_t cert
, key_type_t key
,
175 identification_t
*id
, bool trusted
)
177 cert_enumerator_t
*e
;
181 .enumerate
= enumerator_enumerate_default
,
182 .venumerate
= _cert_enumerator_enumerate
,
183 .destroy
= _cert_enumerator_destroy
,
186 if (id
&& id
->get_type(id
) != ID_ANY
)
188 e
->inner
= this->db
->query(this->db
,
189 "SELECT c.type, c.data FROM certificates AS c "
190 "JOIN certificate_identity AS ci ON c.id = ci.certificate "
191 "JOIN identities AS i ON ci.identity = i.id "
192 "WHERE i.type = ? AND i.data = ? AND "
193 "(? OR c.type = ?) AND (? OR c.keytype = ?)",
194 DB_INT
, id
->get_type(id
), DB_BLOB
, id
->get_encoding(id
),
195 DB_INT
, cert
== CERT_ANY
, DB_INT
, cert
,
196 DB_INT
, key
== KEY_ANY
, DB_INT
, key
,
201 e
->inner
= this->db
->query(this->db
,
202 "SELECT c.type, c.data FROM certificates AS c WHERE "
203 "(? OR c.type = ?) AND (? OR c.keytype = ?)",
204 DB_INT
, cert
== CERT_ANY
, DB_INT
, cert
,
205 DB_INT
, key
== KEY_ANY
, DB_INT
, key
,
218 * enumerator over shared keys
221 /** implements enumerator */
223 /** inner SQL enumerator */
225 /** own identity is defined */
227 /** remote identity is defined */
229 /** currently enumerated private key */
230 shared_key_t
*current
;
231 } shared_enumerator_t
;
233 METHOD(enumerator_t
, shared_enumerator_enumerate
, bool,
234 shared_enumerator_t
*this, va_list args
)
236 shared_key_t
**shared
;
237 id_match_t
*me
, *other
;
241 VA_ARGS_VGET(args
, shared
, me
, other
);
243 DESTROY_IF(this->current
);
244 while (this->inner
->enumerate(this->inner
, &type
, &blob
))
246 this->current
= shared_key_create(type
, chunk_clone(blob
));
249 *shared
= this->current
;
252 *me
= this->me_defined
? ID_MATCH_PERFECT
: ID_MATCH_ANY
;
256 *other
= this->other_defined
? ID_MATCH_PERFECT
: ID_MATCH_ANY
;
261 this->current
= NULL
;
265 METHOD(enumerator_t
, shared_enumerator_destroy
, void,
266 shared_enumerator_t
*this)
268 DESTROY_IF(this->current
);
269 this->inner
->destroy(this->inner
);
273 METHOD(credential_set_t
, create_shared_enumerator
, enumerator_t
*,
274 private_sql_cred_t
*this, shared_key_type_t type
,
275 identification_t
*me
, identification_t
*other
)
277 shared_enumerator_t
*e
;
278 bool me_defined
, other_defined
;
280 me_defined
= me
&& me
->get_type(me
) != ID_ANY
;
281 other_defined
= other
&& other
->get_type(other
) != ID_ANY
;
285 .enumerate
= enumerator_enumerate_default
,
286 .venumerate
= _shared_enumerator_enumerate
,
287 .destroy
= _shared_enumerator_destroy
,
289 .me_defined
= me_defined
,
290 .other_defined
= other_defined
,
292 if (!me_defined
&& !other_defined
)
294 e
->inner
= this->db
->query(this->db
,
295 "SELECT s.type, s.data FROM shared_secrets AS s "
296 "WHERE (? OR s.type = ?)",
297 DB_INT
, type
== SHARED_ANY
, DB_INT
, type
,
300 else if (me_defined
&& other_defined
)
302 e
->inner
= this->db
->query(this->db
,
303 "SELECT s.type, s.data FROM shared_secrets AS s "
304 "JOIN shared_secret_identity AS sm ON s.id = sm.shared_secret "
305 "JOIN identities AS m ON sm.identity = m.id "
306 "JOIN shared_secret_identity AS so ON s.id = so.shared_secret "
307 "JOIN identities AS o ON so.identity = o.id "
308 "WHERE m.type = ? AND m.data = ? AND o.type = ? AND o.data = ? "
309 "AND (? OR s.type = ?)",
310 DB_INT
, me
->get_type(me
), DB_BLOB
, me
->get_encoding(me
),
311 DB_INT
, other
->get_type(other
), DB_BLOB
, other
->get_encoding(other
),
312 DB_INT
, type
== SHARED_ANY
, DB_INT
, type
,
317 identification_t
*id
= me_defined
? me
: other
;
319 e
->inner
= this->db
->query(this->db
,
320 "SELECT s.type, s.data FROM shared_secrets AS s "
321 "JOIN shared_secret_identity AS si ON s.id = si.shared_secret "
322 "JOIN identities AS i ON si.identity = i.id "
323 "WHERE i.type = ? AND i.data = ? AND (? OR s.type = ?)",
324 DB_INT
, id
->get_type(id
), DB_BLOB
, id
->get_encoding(id
),
325 DB_INT
, type
== SHARED_ANY
, DB_INT
, type
,
338 * enumerator over CDPs
341 /** implements enumerator_t */
343 /** inner SQL enumerator */
345 /** currently enumerated string */
353 /** any available CDP */
357 /** OCSP Responder */
361 METHOD(enumerator_t
, cdp_enumerator_enumerate
, bool,
362 cdp_enumerator_t
*this, va_list args
)
366 VA_ARGS_VGET(args
, uri
);
369 while (this->inner
->enumerate(this->inner
, &text
))
371 *uri
= this->current
= strdup(text
);
374 this->current
= NULL
;
378 METHOD(enumerator_t
, cdp_enumerator_destroy
, void,
379 cdp_enumerator_t
*this)
382 this->inner
->destroy(this->inner
);
386 METHOD(credential_set_t
, create_cdp_enumerator
, enumerator_t
*,
387 private_sql_cred_t
*this, certificate_type_t type
, identification_t
*id
)
393 { /* we serve CRLs and OCSP responders */
395 cdp_type
= CDP_TYPE_CRL
;
397 case CERT_X509_OCSP_RESPONSE
:
398 cdp_type
= CDP_TYPE_OCSP
;
401 cdp_type
= CDP_TYPE_ANY
;
408 .enumerate
= enumerator_enumerate_default
,
409 .venumerate
= _cdp_enumerator_enumerate
,
410 .destroy
= _cdp_enumerator_destroy
,
413 if (id
&& id
->get_type(id
) != ID_ANY
)
415 e
->inner
= this->db
->query(this->db
,
416 "SELECT dp.uri FROM certificate_distribution_points AS dp "
417 "JOIN certificate_authorities AS ca ON ca.id = dp.ca "
418 "JOIN certificates AS c ON c.id = ca.certificate "
419 "JOIN certificate_identity AS ci ON c.id = ci.certificate "
420 "JOIN identities AS i ON ci.identity = i.id "
421 "WHERE i.type = ? AND i.data = ? AND (? OR dp.type = ?)",
422 DB_INT
, id
->get_type(id
), DB_BLOB
, id
->get_encoding(id
),
423 DB_INT
, cdp_type
== CDP_TYPE_ANY
, DB_INT
, cdp_type
,
428 e
->inner
= this->db
->query(this->db
,
429 "SELECT dp.uri FROM certificate_distribution_points AS dp "
430 "WHERE (? OR dp.type = ?)",
431 DB_INT
, cdp_type
== CDP_TYPE_ANY
, DB_INT
, cdp_type
,
442 METHOD(credential_set_t
, cache_cert
, void,
443 private_sql_cred_t
*this, certificate_t
*cert
)
445 /* TODO: implement CRL caching to database */
448 METHOD(sql_cred_t
, destroy
, void,
449 private_sql_cred_t
*this)
455 * Described in header.
457 sql_cred_t
*sql_cred_create(database_t
*db
)
459 private_sql_cred_t
*this;
464 .create_private_enumerator
= _create_private_enumerator
,
465 .create_cert_enumerator
= _create_cert_enumerator
,
466 .create_shared_enumerator
= _create_shared_enumerator
,
467 .create_cdp_enumerator
= _create_cdp_enumerator
,
468 .cache_cert
= _cache_cert
,
475 return &this->public;