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