added credential factory support for BULD_NOT_BEFORE_TIME and BUILD_NOT_AFTER_TIME
[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 typedef struct private_credential_factory_t private_credential_factory_t;
26
27 /**
28 * private data of credential_factory
29 */
30 struct private_credential_factory_t {
31
32 /**
33 * public functions
34 */
35 credential_factory_t public;
36
37 /**
38 * list with entry_t
39 */
40 linked_list_t *constructors;
41
42 /**
43 * mutex to lock access to modules
44 */
45 mutex_t *mutex;
46 };
47
48 typedef struct entry_t entry_t;
49 struct entry_t {
50 /** kind of credential builder */
51 credential_type_t type;
52 /** subtype of credential, e.g. certificate_type_t */
53 int subtype;
54 /** builder construction function */
55 builder_constructor_t constructor;
56 };
57
58 /**
59 * Implementation of credential_factory_t.create_builder.
60 */
61 static builder_t* create_builder(private_credential_factory_t *this,
62 credential_type_t type, int subtype)
63 {
64 enumerator_t *enumerator;
65 entry_t *entry;
66 builder_t *builder = NULL;
67
68 this->mutex->lock(this->mutex);
69 enumerator = this->constructors->create_enumerator(this->constructors);
70 while (enumerator->enumerate(enumerator, &entry))
71 {
72 if (entry->type == type && entry->subtype == subtype)
73 {
74 builder = entry->constructor(subtype);
75 if (builder)
76 {
77 break;
78 }
79 }
80 }
81 enumerator->destroy(enumerator);
82 this->mutex->unlock(this->mutex);
83 return builder;
84 }
85
86 /**
87 * Implementation of credential_factory_t.add_builder_constructor.
88 */
89 static void add_builder(private_credential_factory_t *this,
90 credential_type_t type, int subtype,
91 builder_constructor_t constructor)
92 {
93 entry_t *entry = malloc_thing(entry_t);
94
95 entry->type = type;
96 entry->subtype = subtype;
97 entry->constructor = constructor;
98 this->mutex->lock(this->mutex);
99 this->constructors->insert_last(this->constructors, entry);
100 this->mutex->unlock(this->mutex);
101 }
102
103 /**
104 * Implementation of credential_factory_t.remove_builder.
105 */
106 static void remove_builder(private_credential_factory_t *this,
107 builder_constructor_t constructor)
108 {
109 enumerator_t *enumerator;
110 entry_t *entry;
111
112 this->mutex->lock(this->mutex);
113 enumerator = this->constructors->create_enumerator(this->constructors);
114 while (enumerator->enumerate(enumerator, &entry))
115 {
116 if (entry->constructor == constructor)
117 {
118 this->constructors->remove_at(this->constructors, enumerator);
119 free(entry);
120 }
121 }
122 enumerator->destroy(enumerator);
123 this->mutex->unlock(this->mutex);
124 }
125
126 /**
127 * Implementation of credential_factory_t.create.
128 */
129 static void* create(private_credential_factory_t *this, credential_type_t type,
130 int subtype, ...)
131 {
132 builder_t *builder;
133 builder_part_t part;
134 va_list args;
135
136 builder = create_builder(this, type, subtype);
137 if (builder)
138 {
139 va_start(args, subtype);
140 while (TRUE)
141 {
142 part = va_arg(args, builder_part_t);
143
144 switch (part)
145 {
146 case BUILD_END:
147 break;
148 case BUILD_BLOB_ASN1_DER:
149 builder->add(builder, part, va_arg(args, chunk_t));
150 continue;
151 case BUILD_X509_FLAG:
152 builder->add(builder, part, va_arg(args, x509_flag_t));
153 continue;
154 case BUILD_KEY_SIZE:
155 builder->add(builder, part, va_arg(args, u_int));
156 continue;
157 case BUILD_NOT_BEFORE_TIME:
158 case BUILD_NOT_AFTER_TIME:
159 builder->add(builder, part, va_arg(args, time_t));
160 continue;
161 case BUILD_SIGNING_KEY:
162 case BUILD_PUBLIC_KEY:
163 case BUILD_SUBJECT:
164 case BUILD_SUBJECT_ALTNAME:
165 case BUILD_ISSUER:
166 case BUILD_ISSUER_ALTNAME:
167 case BUILD_SIGNING_CERT:
168 case BUILD_CA_CERT:
169 case BUILD_CERT:
170 builder->add(builder, part, va_arg(args, void*));
171 continue;
172 default:
173 DBG1("builder part %N not supported by factory",
174 builder_part_names, part);
175 break;
176 }
177 break;
178 }
179 va_end(args);
180
181 return builder->build(builder);
182 }
183
184 /** shredder all data on failure */
185 va_start(args, subtype);
186 while (TRUE)
187 {
188 part = va_arg(args, builder_part_t);
189
190 switch (part)
191 {
192 case BUILD_END:
193 break;
194 case BUILD_BLOB_ASN1_DER:
195 {
196 chunk_t chunk = va_arg(args, chunk_t);
197 free(chunk.ptr);
198 continue;
199 }
200 case BUILD_SIGNING_KEY:
201 {
202 private_key_t *private = va_arg(args, private_key_t*);
203 private->destroy(private);
204 continue;
205 }
206 case BUILD_PUBLIC_KEY:
207 {
208 public_key_t *public = va_arg(args, public_key_t*);
209 public->destroy(public);
210 continue;
211 }
212 case BUILD_SUBJECT:
213 case BUILD_SUBJECT_ALTNAME:
214 case BUILD_ISSUER:
215 case BUILD_ISSUER_ALTNAME:
216 {
217 identification_t *id = va_arg(args, identification_t*);
218 id->destroy(id);
219 continue;
220 }
221 case BUILD_SIGNING_CERT:
222 case BUILD_CA_CERT:
223 case BUILD_CERT:
224 {
225 certificate_t *cert = va_arg(args, certificate_t*);
226 cert->destroy(cert);
227 continue;
228 }
229 case BUILD_KEY_SIZE:
230 case BUILD_X509_FLAG:
231 continue;
232 default:
233 DBG1("builder part %N not supported by factory",
234 builder_part_names, part);
235 continue;
236 }
237 break;
238 }
239 va_end(args);
240 return NULL;
241 }
242
243 /**
244 * Implementation of credential_factory_t.destroy
245 */
246 static void destroy(private_credential_factory_t *this)
247 {
248 this->constructors->destroy_function(this->constructors, free);
249 this->mutex->destroy(this->mutex);
250 free(this);
251 }
252
253 /*
254 * see header file
255 */
256 credential_factory_t *credential_factory_create()
257 {
258 private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
259
260 this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
261 this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder;
262 this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
263 this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
264 this->public.destroy = (void(*)(credential_factory_t*))destroy;
265
266 this->constructors = linked_list_create();
267
268 this->mutex = mutex_create(MUTEX_RECURSIVE);
269
270 return &this->public;
271 }
272