updated Doxyfile
[strongswan.git] / src / libstrongswan / credentials / credential_factory.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 * $Id$
16 */
17
18 #include "credential_factory.h"
19
20 #include <debug.h>
21 #include <utils/linked_list.h>
22 #include <utils/mutex.h>
23 #include <credentials/certificates/x509.h>
24
25 ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CERTIFICATE,
26 "CRED_PRIVATE_KEY",
27 "CRED_PUBLIC_KEY",
28 "CRED_CERTIFICATE",
29 );
30
31 typedef struct private_credential_factory_t private_credential_factory_t;
32
33 /**
34 * private data of credential_factory
35 */
36 struct private_credential_factory_t {
37
38 /**
39 * public functions
40 */
41 credential_factory_t public;
42
43 /**
44 * list with entry_t
45 */
46 linked_list_t *constructors;
47
48 /**
49 * lock access to builders
50 */
51 rwlock_t *lock;
52 };
53
54 typedef struct entry_t entry_t;
55 struct entry_t {
56 /** kind of credential builder */
57 credential_type_t type;
58 /** subtype of credential, e.g. certificate_type_t */
59 int subtype;
60 /** builder construction function */
61 builder_constructor_t constructor;
62 };
63
64 /**
65 * type/subtype filter function for builder_enumerator
66 */
67 static bool builder_filter(entry_t *data, entry_t **in, builder_t **out)
68 {
69 if (data->type == (*in)->type &&
70 data->subtype == (*in)->subtype)
71 {
72 *out = (*in)->constructor(data->subtype);
73 return TRUE;
74 }
75 return FALSE;
76 }
77
78 /**
79 * Implementation of credential_factory_t.create_builder_enumerator.
80 */
81 static enumerator_t* create_builder_enumerator(
82 private_credential_factory_t *this, credential_type_t type, int subtype)
83 {
84 entry_t *data = malloc_thing(entry_t);
85
86 data->type = type;
87 data->subtype = subtype;
88
89 this->lock->read_lock(this->lock);
90 return enumerator_create_cleaner(
91 enumerator_create_filter(
92 this->constructors->create_enumerator(this->constructors),
93 (void*)builder_filter, data, free),
94 (void*)this->lock->unlock, this->lock);
95 }
96
97 /**
98 * Implementation of credential_factory_t.add_builder_constructor.
99 */
100 static void add_builder(private_credential_factory_t *this,
101 credential_type_t type, int subtype,
102 builder_constructor_t constructor)
103 {
104 entry_t *entry = malloc_thing(entry_t);
105
106 entry->type = type;
107 entry->subtype = subtype;
108 entry->constructor = constructor;
109 this->lock->write_lock(this->lock);
110 this->constructors->insert_last(this->constructors, entry);
111 this->lock->unlock(this->lock);
112 }
113
114 /**
115 * Implementation of credential_factory_t.remove_builder.
116 */
117 static void remove_builder(private_credential_factory_t *this,
118 builder_constructor_t constructor)
119 {
120 enumerator_t *enumerator;
121 entry_t *entry;
122
123 this->lock->write_lock(this->lock);
124 enumerator = this->constructors->create_enumerator(this->constructors);
125 while (enumerator->enumerate(enumerator, &entry))
126 {
127 if (entry->constructor == constructor)
128 {
129 this->constructors->remove_at(this->constructors, enumerator);
130 free(entry);
131 }
132 }
133 enumerator->destroy(enumerator);
134 this->lock->unlock(this->lock);
135 }
136
137 /**
138 * Implementation of credential_factory_t.create.
139 */
140 static void* create(private_credential_factory_t *this, credential_type_t type,
141 int subtype, ...)
142 {
143 enumerator_t *enumerator;
144 builder_t *builder;
145 builder_part_t part;
146 va_list args;
147 void* construct = NULL;
148
149 enumerator = create_builder_enumerator(this, type, subtype);
150 while (enumerator->enumerate(enumerator, &builder))
151 {
152 va_start(args, subtype);
153 while (TRUE)
154 {
155 part = va_arg(args, builder_part_t);
156 switch (part)
157 {
158 case BUILD_END:
159 break;
160 case BUILD_BLOB_ASN1_DER:
161 case BUILD_SERIAL:
162 builder->add(builder, part, va_arg(args, chunk_t));
163 continue;
164 case BUILD_X509_FLAG:
165 builder->add(builder, part, va_arg(args, x509_flag_t));
166 continue;
167 case BUILD_KEY_SIZE:
168 builder->add(builder, part, va_arg(args, u_int));
169 continue;
170 case BUILD_NOT_BEFORE_TIME:
171 case BUILD_NOT_AFTER_TIME:
172 builder->add(builder, part, va_arg(args, time_t));
173 continue;
174 case BUILD_BLOB_ASN1_PEM:
175 case BUILD_FROM_FILE:
176 case BUILD_AGENT_SOCKET:
177 case BUILD_SIGNING_KEY:
178 case BUILD_PUBLIC_KEY:
179 case BUILD_SUBJECT:
180 case BUILD_SUBJECT_ALTNAME:
181 case BUILD_ISSUER:
182 case BUILD_ISSUER_ALTNAME:
183 case BUILD_SIGNING_CERT:
184 case BUILD_CA_CERT:
185 case BUILD_CERT:
186 case BUILD_IETF_GROUP_ATTR:
187 case BUILD_SMARTCARD_KEYID:
188 case BUILD_SMARTCARD_PIN:
189 builder->add(builder, part, va_arg(args, void*));
190 continue;
191 /* no default to get a compiler warning */
192 }
193 break;
194 }
195 va_end(args);
196
197 construct = builder->build(builder);
198 if (construct)
199 {
200 break;
201 }
202 }
203 enumerator->destroy(enumerator);
204 if (!construct)
205 {
206 DBG1("failed to create a builder for credential type %N,"
207 " subtype (%d)", credential_type_names, type, subtype);
208 }
209 return construct;
210 }
211
212 /**
213 * Implementation of credential_factory_t.destroy
214 */
215 static void destroy(private_credential_factory_t *this)
216 {
217 this->constructors->destroy_function(this->constructors, free);
218 this->lock->destroy(this->lock);
219 free(this);
220 }
221
222 /*
223 * see header file
224 */
225 credential_factory_t *credential_factory_create()
226 {
227 private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
228
229 this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
230 this->public.create_builder_enumerator = (enumerator_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder_enumerator;
231 this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
232 this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
233 this->public.destroy = (void(*)(credential_factory_t*))destroy;
234
235 this->constructors = linked_list_create();
236
237 this->lock = rwlock_create(RWLOCK_DEFAULT);
238
239 return &this->public;
240 }
241