2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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 <threading/rwlock.h>
19 #include <utils/linked_list.h>
21 typedef struct private_mem_cred_t private_mem_cred_t
;
24 * Private data of an mem_cred_t object.
26 struct private_mem_cred_t
{
29 * Public mem_cred_t interface.
39 * List of trusted certificates, certificate_t
41 linked_list_t
*trusted
;
44 * List of trusted and untrusted certificates, certificate_t
46 linked_list_t
*untrusted
;
49 * List of private keys, private_key_t
54 * List of shared keys, as shared_entry_t
56 linked_list_t
*shared
;
60 * Data for the certificate enumerator
64 certificate_type_t cert
;
72 static void cert_data_destroy(cert_data_t
*data
)
74 data
->lock
->unlock(data
->lock
);
79 * filter function for certs enumerator
81 static bool certs_filter(cert_data_t
*data
, certificate_t
**in
, certificate_t
**out
)
84 certificate_t
*cert
= *in
;
86 if (data
->cert
== CERT_ANY
|| data
->cert
== cert
->get_type(cert
))
88 public = cert
->get_public_key(cert
);
91 if (data
->key
== KEY_ANY
|| data
->key
== public->get_type(public))
93 if (public->has_fingerprint(public,
94 data
->id
->get_encoding(data
->id
)))
96 public->destroy(public);
101 public->destroy(public);
103 else if (data
->key
!= KEY_ANY
)
107 if (data
->id
== NULL
|| cert
->has_subject(cert
, data
->id
))
116 METHOD(credential_set_t
, create_cert_enumerator
, enumerator_t
*,
117 private_mem_cred_t
*this, certificate_type_t cert
, key_type_t key
,
118 identification_t
*id
, bool trusted
)
121 enumerator_t
*enumerator
;
129 this->lock
->read_lock(this->lock
);
132 enumerator
= this->trusted
->create_enumerator(this->trusted
);
136 enumerator
= this->untrusted
->create_enumerator(this->untrusted
);
138 return enumerator_create_filter(enumerator
, (void*)certs_filter
, data
,
139 (void*)cert_data_destroy
);
142 METHOD(mem_cred_t
, add_cert
, void,
143 private_mem_cred_t
*this, bool trusted
, certificate_t
*cert
)
145 this->lock
->write_lock(this->lock
);
148 this->trusted
->insert_last(this->trusted
, cert
->get_ref(cert
));
150 this->untrusted
->insert_last(this->untrusted
, cert
);
151 this->lock
->unlock(this->lock
);
155 * Data for key enumerator
160 identification_t
*id
;
164 * Destroy key enumerator data
166 static void key_data_destroy(key_data_t
*data
)
168 data
->lock
->unlock(data
->lock
);
173 * filter function for private key enumerator
175 static bool key_filter(key_data_t
*data
, private_key_t
**in
, private_key_t
**out
)
180 if (data
->type
== KEY_ANY
|| data
->type
== key
->get_type(key
))
182 if (data
->id
== NULL
||
183 key
->has_fingerprint(key
, data
->id
->get_encoding(data
->id
)))
192 METHOD(credential_set_t
, create_private_enumerator
, enumerator_t
*,
193 private_mem_cred_t
*this, key_type_t type
, identification_t
*id
)
202 this->lock
->read_lock(this->lock
);
203 return enumerator_create_filter(this->keys
->create_enumerator(this->keys
),
204 (void*)key_filter
, data
, (void*)key_data_destroy
);
207 METHOD(mem_cred_t
, add_key
, void,
208 private_mem_cred_t
*this, private_key_t
*key
)
210 this->lock
->write_lock(this->lock
);
211 this->keys
->insert_last(this->keys
, key
);
212 this->lock
->unlock(this->lock
);
220 shared_key_t
*shared
;
221 /* list of owners, identification_t */
222 linked_list_t
*owners
;
226 * Clean up a shared entry
228 static void shared_entry_destroy(shared_entry_t
*entry
)
230 entry
->owners
->destroy_offset(entry
->owners
,
231 offsetof(identification_t
, destroy
));
232 entry
->shared
->destroy(entry
->shared
);
237 * Data for the shared_key enumerator
241 identification_t
*me
;
242 identification_t
*other
;
243 shared_key_type_t type
;
247 * free shared key enumerator data and unlock list
249 static void shared_data_destroy(shared_data_t
*data
)
251 data
->lock
->unlock(data
->lock
);
256 * Get the best match of an owner in an entry.
258 static id_match_t
has_owner(shared_entry_t
*entry
, identification_t
*owner
)
260 enumerator_t
*enumerator
;
261 id_match_t match
, best
= ID_MATCH_NONE
;
262 identification_t
*current
;
264 enumerator
= entry
->owners
->create_enumerator(entry
->owners
);
265 while (enumerator
->enumerate(enumerator
, ¤t
))
267 match
= owner
->matches(owner
, current
);
273 enumerator
->destroy(enumerator
);
278 * enumerator filter function for shared entries
280 static bool shared_filter(shared_data_t
*data
,
281 shared_entry_t
**in
, shared_key_t
**out
,
282 void **unused1
, id_match_t
*me
,
283 void **unused2
, id_match_t
*other
)
285 id_match_t my_match
= ID_MATCH_NONE
, other_match
= ID_MATCH_NONE
;
286 shared_entry_t
*entry
= *in
;
288 if (data
->type
!= SHARED_ANY
&&
289 entry
->shared
->get_type(entry
->shared
) != data
->type
)
295 my_match
= has_owner(entry
, data
->me
);
299 other_match
= has_owner(entry
, data
->other
);
301 if ((data
->me
|| data
->other
) && (!my_match
&& !other_match
))
305 *out
= entry
->shared
;
312 *other
= other_match
;
317 METHOD(credential_set_t
, create_shared_enumerator
, enumerator_t
*,
318 private_mem_cred_t
*this, shared_key_type_t type
,
319 identification_t
*me
, identification_t
*other
)
329 data
->lock
->read_lock(data
->lock
);
330 return enumerator_create_filter(
331 this->shared
->create_enumerator(this->shared
),
332 (void*)shared_filter
, data
, (void*)shared_data_destroy
);
335 METHOD(mem_cred_t
, add_shared
, void,
336 private_mem_cred_t
*this, shared_key_t
*shared
, ...)
338 shared_entry_t
*entry
;
339 identification_t
*id
;
344 .owners
= linked_list_create(),
347 va_start(args
, shared
);
350 id
= va_arg(args
, identification_t
*);
353 entry
->owners
->insert_last(entry
->owners
, id
);
359 this->lock
->write_lock(this->lock
);
360 this->shared
->insert_last(this->shared
, entry
);
361 this->lock
->unlock(this->lock
);
364 METHOD(mem_cred_t
, destroy
, void,
365 private_mem_cred_t
*this)
367 this->trusted
->destroy_offset(this->trusted
,
368 offsetof(certificate_t
, destroy
));
369 this->untrusted
->destroy_offset(this->untrusted
,
370 offsetof(certificate_t
, destroy
));
371 this->keys
->destroy_offset(this->keys
, offsetof(private_key_t
, destroy
));
372 this->shared
->destroy_function(this->shared
, (void*)shared_entry_destroy
);
373 this->lock
->destroy(this->lock
);
380 mem_cred_t
*mem_cred_create()
382 private_mem_cred_t
*this;
387 .create_shared_enumerator
= _create_shared_enumerator
,
388 .create_private_enumerator
= _create_private_enumerator
,
389 .create_cert_enumerator
= _create_cert_enumerator
,
390 .create_cdp_enumerator
= (void*)return_null
,
391 .cache_cert
= (void*)nop
,
393 .add_cert
= _add_cert
,
395 .add_shared
= _add_shared
,
398 .trusted
= linked_list_create(),
399 .untrusted
= linked_list_create(),
400 .keys
= linked_list_create(),
401 .shared
= linked_list_create(),
402 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
405 return &this->public;