Migrated eap_simaka_pseudonym_provider_t to INIT/METHOD macros.
[strongswan.git] / src / libcharon / plugins / eap_simaka_pseudonym / eap_simaka_pseudonym_provider.c
1 /*
2 * Copyright (C) 2009 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
16 #include "eap_simaka_pseudonym_provider.h"
17
18 #include <utils/hashtable.h>
19
20 typedef struct private_eap_simaka_pseudonym_provider_t private_eap_simaka_pseudonym_provider_t;
21
22 /**
23 * Private data of an eap_simaka_pseudonym_provider_t object.
24 */
25 struct private_eap_simaka_pseudonym_provider_t {
26
27 /**
28 * Public eap_simaka_pseudonym_provider_t interface.
29 */
30 eap_simaka_pseudonym_provider_t public;
31
32 /**
33 * Permanent -> pseudonym mappings
34 */
35 hashtable_t *pseudonym;
36
37 /**
38 * Reverse pseudonym -> permanent mappings
39 */
40 hashtable_t *permanent;
41
42 /**
43 * RNG for pseudonyms/reauth identities
44 */
45 rng_t *rng;
46 };
47
48 /**
49 * hashtable hash function
50 */
51 static u_int hash(identification_t *key)
52 {
53 return chunk_hash(key->get_encoding(key));
54 }
55
56 /**
57 * hashtable equals function
58 */
59 static bool equals(identification_t *key1, identification_t *key2)
60 {
61 return key1->equals(key1, key2);
62 }
63
64 METHOD(simaka_provider_t, is_pseudonym, identification_t*,
65 private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
66 {
67 identification_t *permanent;
68
69 permanent = this->permanent->get(this->permanent, id);
70 if (permanent)
71 {
72 return permanent->clone(permanent);
73 }
74 return NULL;
75 }
76
77 /**
78 * Generate a random identity
79 */
80 static identification_t *gen_identity(
81 private_eap_simaka_pseudonym_provider_t *this)
82 {
83 char buf[8], hex[sizeof(buf) * 2 + 1];
84
85 this->rng->get_bytes(this->rng, sizeof(buf), buf);
86 chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE);
87
88 return identification_create_from_string(hex);
89 }
90
91 METHOD(simaka_provider_t, gen_pseudonym, identification_t*,
92 private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
93 {
94 identification_t *pseudonym, *permanent;
95
96 /* remove old entry */
97 pseudonym = this->pseudonym->remove(this->pseudonym, id);
98 if (pseudonym)
99 {
100 permanent = this->permanent->remove(this->permanent, pseudonym);
101 if (permanent)
102 {
103 permanent->destroy(permanent);
104 }
105 pseudonym->destroy(pseudonym);
106 }
107
108 pseudonym = gen_identity(this);
109
110 /* create new entries */
111 id = id->clone(id);
112 this->pseudonym->put(this->pseudonym, id, pseudonym);
113 this->permanent->put(this->permanent, pseudonym, id);
114
115 return pseudonym->clone(pseudonym);
116 }
117
118 METHOD(eap_simaka_pseudonym_provider_t, destroy, void,
119 private_eap_simaka_pseudonym_provider_t *this)
120 {
121 enumerator_t *enumerator;
122 identification_t *id;
123 void *key;
124
125 enumerator = this->pseudonym->create_enumerator(this->pseudonym);
126 while (enumerator->enumerate(enumerator, &key, &id))
127 {
128 id->destroy(id);
129 }
130 enumerator->destroy(enumerator);
131
132 enumerator = this->permanent->create_enumerator(this->permanent);
133 while (enumerator->enumerate(enumerator, &key, &id))
134 {
135 id->destroy(id);
136 }
137 enumerator->destroy(enumerator);
138
139 this->pseudonym->destroy(this->pseudonym);
140 this->permanent->destroy(this->permanent);
141 this->rng->destroy(this->rng);
142 free(this);
143 }
144
145 /**
146 * See header
147 */
148 eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create()
149 {
150 private_eap_simaka_pseudonym_provider_t *this;
151
152 INIT(this,
153 .public = {
154 .provider = {
155 .get_triplet = (void*)return_false,
156 .get_quintuplet = (void*)return_false,
157 .resync = (void*)return_false,
158 .is_pseudonym = _is_pseudonym,
159 .gen_pseudonym = _gen_pseudonym,
160 .is_reauth = (void*)return_null,
161 .gen_reauth = (void*)return_null,
162 },
163 .destroy = _destroy,
164 },
165 .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
166 );
167 if (!this->rng)
168 {
169 free(this);
170 return NULL;
171 }
172 this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0);
173 this->permanent = hashtable_create((void*)hash, (void*)equals, 0);
174
175 return &this->public;
176 }
177