2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include "credential_factory.h"
21 #include <utils/linked_list.h>
22 #include <utils/mutex.h>
23 #include <credentials/certificates/x509.h>
25 ENUM(credential_type_names
, CRED_PRIVATE_KEY
, CRED_CERTIFICATE
,
31 typedef struct private_credential_factory_t private_credential_factory_t
;
34 * private data of credential_factory
36 struct private_credential_factory_t
{
41 credential_factory_t
public;
46 linked_list_t
*constructors
;
49 * mutex to lock access to modules
54 typedef struct entry_t entry_t
;
56 /** kind of credential builder */
57 credential_type_t type
;
58 /** subtype of credential, e.g. certificate_type_t */
60 /** builder construction function */
61 builder_constructor_t constructor
;
65 * Implementation of credential_factory_t.create_builder.
67 static builder_t
* create_builder(private_credential_factory_t
*this,
68 credential_type_t type
, int subtype
)
70 enumerator_t
*enumerator
;
72 builder_t
*builder
= NULL
;
74 this->mutex
->lock(this->mutex
);
75 enumerator
= this->constructors
->create_enumerator(this->constructors
);
76 while (enumerator
->enumerate(enumerator
, &entry
))
78 if (entry
->type
== type
&& entry
->subtype
== subtype
)
80 builder
= entry
->constructor(subtype
);
87 enumerator
->destroy(enumerator
);
88 this->mutex
->unlock(this->mutex
);
93 * Implementation of credential_factory_t.add_builder_constructor.
95 static void add_builder(private_credential_factory_t
*this,
96 credential_type_t type
, int subtype
,
97 builder_constructor_t constructor
)
99 entry_t
*entry
= malloc_thing(entry_t
);
102 entry
->subtype
= subtype
;
103 entry
->constructor
= constructor
;
104 this->mutex
->lock(this->mutex
);
105 this->constructors
->insert_last(this->constructors
, entry
);
106 this->mutex
->unlock(this->mutex
);
110 * Implementation of credential_factory_t.remove_builder.
112 static void remove_builder(private_credential_factory_t
*this,
113 builder_constructor_t constructor
)
115 enumerator_t
*enumerator
;
118 this->mutex
->lock(this->mutex
);
119 enumerator
= this->constructors
->create_enumerator(this->constructors
);
120 while (enumerator
->enumerate(enumerator
, &entry
))
122 if (entry
->constructor
== constructor
)
124 this->constructors
->remove_at(this->constructors
, enumerator
);
128 enumerator
->destroy(enumerator
);
129 this->mutex
->unlock(this->mutex
);
133 * Implementation of credential_factory_t.create.
135 static void* create(private_credential_factory_t
*this, credential_type_t type
,
142 builder
= create_builder(this, type
, subtype
);
145 va_start(args
, subtype
);
148 part
= va_arg(args
, builder_part_t
);
154 case BUILD_BLOB_ASN1_DER
:
156 builder
->add(builder
, part
, va_arg(args
, chunk_t
));
158 case BUILD_X509_FLAG
:
159 builder
->add(builder
, part
, va_arg(args
, x509_flag_t
));
162 builder
->add(builder
, part
, va_arg(args
, u_int
));
164 case BUILD_NOT_BEFORE_TIME
:
165 case BUILD_NOT_AFTER_TIME
:
166 builder
->add(builder
, part
, va_arg(args
, time_t));
168 case BUILD_FROM_FILE
:
169 case BUILD_SIGNING_KEY
:
170 case BUILD_PUBLIC_KEY
:
172 case BUILD_SUBJECT_ALTNAME
:
174 case BUILD_ISSUER_ALTNAME
:
175 case BUILD_SIGNING_CERT
:
178 case BUILD_IETF_GROUP_ATTR
:
179 builder
->add(builder
, part
, va_arg(args
, void*));
182 DBG1("builder part %N not supported by factory",
183 builder_part_names
, part
);
190 return builder
->build(builder
);
194 DBG1("failed to create a builder for credential type %N,"
195 " subtype (%d)", credential_type_names
, type
, subtype
);
198 /** shredder all data on failure */
199 va_start(args
, subtype
);
202 part
= va_arg(args
, builder_part_t
);
208 case BUILD_BLOB_ASN1_DER
:
210 chunk_t chunk
= va_arg(args
, chunk_t
);
216 va_arg(args
, chunk_t
);
219 case BUILD_X509_FLAG
:
221 va_arg(args
, x509_flag_t
);
229 case BUILD_NOT_BEFORE_TIME
:
230 case BUILD_NOT_AFTER_TIME
:
232 va_arg(args
, time_t);
235 case BUILD_SIGNING_KEY
:
237 private_key_t
*private = va_arg(args
, private_key_t
*);
238 private->destroy(private);
241 case BUILD_PUBLIC_KEY
:
243 public_key_t
*public = va_arg(args
, public_key_t
*);
244 public->destroy(public);
248 case BUILD_SUBJECT_ALTNAME
:
250 case BUILD_ISSUER_ALTNAME
:
252 identification_t
*id
= va_arg(args
, identification_t
*);
256 case BUILD_SIGNING_CERT
:
260 certificate_t
*cert
= va_arg(args
, certificate_t
*);
264 case BUILD_FROM_FILE
:
265 case BUILD_IETF_GROUP_ATTR
:
271 DBG1("builder part %N not supported by factory",
272 builder_part_names
, part
);
282 * Implementation of credential_factory_t.destroy
284 static void destroy(private_credential_factory_t
*this)
286 this->constructors
->destroy_function(this->constructors
, free
);
287 this->mutex
->destroy(this->mutex
);
294 credential_factory_t
*credential_factory_create()
296 private_credential_factory_t
*this = malloc_thing(private_credential_factory_t
);
298 this->public.create
= (void*(*)(credential_factory_t
*, credential_type_t type
, int subtype
, ...))create
;
299 this->public.create_builder
= (builder_t
*(*)(credential_factory_t
*, credential_type_t type
, int subtype
))create_builder
;
300 this->public.add_builder
= (void(*)(credential_factory_t
*,credential_type_t type
, int subtype
, builder_constructor_t constructor
))add_builder
;
301 this->public.remove_builder
= (void(*)(credential_factory_t
*,builder_constructor_t constructor
))remove_builder
;
302 this->public.destroy
= (void(*)(credential_factory_t
*))destroy
;
304 this->constructors
= linked_list_create();
306 this->mutex
= mutex_create(MUTEX_RECURSIVE
);
308 return &this->public;