|
|
1.1 misho 1: /*
2: * Copyright (C) 2008 Martin Willi
3: * HSR 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, va_list args)
54: {
55: private_key_t **key;
56: chunk_t chunk;
57:
58: VA_ARGS_VGET(args, key);
59:
60: DESTROY_IF(this->current);
61: while (this->inner->enumerate(this->inner, &chunk))
62: {
63: this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
64: BUILD_BLOB_ASN1_DER, chunk,
65: BUILD_END);
66: if (this->current)
67: {
68: *key = this->current;
69: return TRUE;
70: }
71: }
72: this->current = NULL;
73: return FALSE;
74: }
75:
76: METHOD(enumerator_t, private_enumerator_destroy, void,
77: private_enumerator_t *this)
78: {
79: DESTROY_IF(this->current);
80: this->inner->destroy(this->inner);
81: free(this);
82: }
83:
84: METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
85: private_medcli_creds_t *this, key_type_t type, identification_t *id)
86: {
87: private_enumerator_t *e;
88:
89: if ((type != KEY_RSA && type != KEY_ANY) ||
90: id == NULL || id->get_type(id) != ID_KEY_ID)
91: {
92: DBG1(DBG_CFG, "%N - %Y", key_type_names, type, id);
93: return NULL;
94: }
95:
96: INIT(e,
97: .public = {
98: .enumerate = enumerator_enumerate_default,
99: .venumerate = _private_enumerator_enumerate,
100: .destroy = _private_enumerator_destroy,
101: },
102: );
103: e->inner = this->db->query(this->db,
104: "SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?",
105: DB_BLOB, id->get_encoding(id),
106: DB_BLOB);
107: if (!e->inner)
108: {
109: free(e);
110: return NULL;
111: }
112: return &e->public;
113: }
114:
115: /**
116: * enumerator over certificates
117: */
118: typedef struct {
119: /** implements enumerator */
120: enumerator_t public;
121: /** inner SQL enumerator */
122: enumerator_t *inner;
123: /** currently enumerated cert */
124: certificate_t *current;
125: /** type of requested key */
126: key_type_t type;
127: } cert_enumerator_t;
128:
129: METHOD(enumerator_t, cert_enumerator_enumerate, bool,
130: cert_enumerator_t *this, va_list args)
131: {
132: certificate_t **cert;
133: public_key_t *public;
134: chunk_t chunk;
135:
136: VA_ARGS_VGET(args, cert);
137:
138: DESTROY_IF(this->current);
139: while (this->inner->enumerate(this->inner, &chunk))
140: {
141: public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
142: BUILD_BLOB_ASN1_DER, chunk,
143: BUILD_END);
144: if (public)
145: {
146: if (this->type == KEY_ANY || this->type == public->get_type(public))
147: {
148: this->current = lib->creds->create(lib->creds,
149: CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
150: BUILD_PUBLIC_KEY, public, BUILD_END);
151: public->destroy(public);
152: if (this->current)
153: {
154: *cert = this->current;
155: return TRUE;
156: }
157: }
158: else
159: {
160: public->destroy(public);
161: }
162: }
163: }
164: this->current = NULL;
165: return FALSE;
166: }
167:
168: METHOD(enumerator_t, cert_enumerator_destroy, void,
169: cert_enumerator_t *this)
170: {
171: DESTROY_IF(this->current);
172: this->inner->destroy(this->inner);
173: free(this);
174: }
175:
176: METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
177: private_medcli_creds_t *this, certificate_type_t cert, key_type_t key,
178: identification_t *id, bool trusted)
179: {
180: cert_enumerator_t *e;
181:
182: if ((cert != CERT_TRUSTED_PUBKEY && cert != CERT_ANY) ||
183: id == NULL || id->get_type(id) != ID_KEY_ID)
184: {
185: return NULL;
186: }
187:
188: INIT(e,
189: .public = {
190: .enumerate = enumerator_enumerate_default,
191: .venumerate = _cert_enumerator_enumerate,
192: .destroy = _cert_enumerator_destroy,
193: },
194: .type = key,
195: );
196: e->inner = this->db->query(this->db,
197: "SELECT PublicKey FROM ClientConfig WHERE KeyId = ? UNION "
198: "SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION "
199: "SELECT PublicKey FROM Connection WHERE KeyId = ?",
200: DB_BLOB, id->get_encoding(id),
201: DB_BLOB, id->get_encoding(id),
202: DB_BLOB, id->get_encoding(id),
203: DB_BLOB);
204: if (!e->inner)
205: {
206: free(e);
207: return NULL;
208: }
209: return &e->public;
210: }
211:
212: METHOD(medcli_creds_t, destroy, void,
213: private_medcli_creds_t *this)
214: {
215: free(this);
216: }
217:
218: /**
219: * Described in header.
220: */
221: medcli_creds_t *medcli_creds_create(database_t *db)
222: {
223: private_medcli_creds_t *this;
224:
225: INIT(this,
226: .public = {
227: .set = {
228: .create_private_enumerator = _create_private_enumerator,
229: .create_cert_enumerator = _create_cert_enumerator,
230: .create_shared_enumerator = (void*)return_null,
231: .create_cdp_enumerator = (void*)return_null,
232: .cache_cert = (void*)nop,
233: },
234: .destroy = _destroy,
235: },
236: .db = db,
237: );
238:
239: return &this->public;
240: }
241: