Removed strayed code fragment
[strongswan.git] / src / charon / plugins / eap_simaka_reauth / eap_simaka_reauth_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_reauth_provider.h"
17
18 #include <daemon.h>
19 #include <utils/hashtable.h>
20
21 typedef struct private_eap_simaka_reauth_provider_t private_eap_simaka_reauth_provider_t;
22
23 /**
24 * Private data of an eap_simaka_reauth_provider_t object.
25 */
26 struct private_eap_simaka_reauth_provider_t {
27
28 /**
29 * Public eap_simaka_reauth_provider_t interface.
30 */
31 eap_simaka_reauth_provider_t public;
32
33 /**
34 * Permanent -> reauth_data_t mappings
35 */
36 hashtable_t *reauth;
37
38 /**
39 * Reverse reauth -> permanent mappings
40 */
41 hashtable_t *permanent;
42
43 /**
44 * RNG for pseudonyms/reauth identities
45 */
46 rng_t *rng;
47 };
48
49 /**
50 * Data associated to a reauthentication identity
51 */
52 typedef struct {
53 /** currently used reauthentication identity */
54 identification_t *id;
55 /** counter value */
56 u_int16_t counter;
57 /** master key */
58 char mk[HASH_SIZE_SHA1];
59 } reauth_data_t;
60
61 /**
62 * hashtable hash function
63 */
64 static u_int hash(identification_t *key)
65 {
66 return chunk_hash(key->get_encoding(key));
67 }
68
69 /**
70 * hashtable equals function
71 */
72 static bool equals(identification_t *key1, identification_t *key2)
73 {
74 return key1->equals(key1, key2);
75 }
76
77 /**
78 * Generate a random identity
79 */
80 static identification_t *gen_identity(private_eap_simaka_reauth_provider_t *this)
81 {
82 char buf[8], hex[sizeof(buf) * 2 + 1];
83
84 this->rng->get_bytes(this->rng, sizeof(buf), buf);
85 chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE);
86
87 return identification_create_from_string(hex);
88 }
89
90 /**
91 * Implementation of sim_provider_t.is_reauth
92 */
93 static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this,
94 identification_t *id, char mk[HASH_SIZE_SHA1],
95 u_int16_t *counter)
96 {
97 identification_t *permanent;
98 reauth_data_t *data;
99
100 /* look up permanent identity */
101 permanent = this->permanent->get(this->permanent, id);
102 if (!permanent)
103 {
104 return NULL;
105 }
106 /* look up reauthentication data */
107 data = this->reauth->get(this->reauth, permanent);
108 if (!data)
109 {
110 return NULL;
111 }
112 *counter = ++data->counter;
113 memcpy(mk, data->mk, HASH_SIZE_SHA1);
114 return permanent->clone(permanent);
115 }
116
117 /**
118 * Implementation of sim_provider_t.gen_reauth
119 */
120 static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this,
121 identification_t *id, char mk[HASH_SIZE_SHA1])
122 {
123 reauth_data_t *data;
124 identification_t *permanent;
125
126 data = this->reauth->get(this->reauth, id);
127 if (data)
128 { /* update existing entry */
129 permanent = this->permanent->remove(this->permanent, data->id);
130 if (permanent)
131 {
132 data->id->destroy(data->id);
133 data->id = gen_identity(this);
134 this->permanent->put(this->permanent, data->id, permanent);
135 }
136 }
137 else
138 { /* generate new entry */
139 data = malloc_thing(reauth_data_t);
140 data->counter = 0;
141 data->id = gen_identity(this);
142 id = id->clone(id);
143 this->reauth->put(this->reauth, id, data);
144 this->permanent->put(this->permanent, data->id, id);
145 }
146 memcpy(data->mk, mk, HASH_SIZE_SHA1);
147
148 return data->id->clone(data->id);
149 }
150
151 /**
152 * Implementation of eap_simaka_reauth_provider_t.destroy.
153 */
154 static void destroy(private_eap_simaka_reauth_provider_t *this)
155 {
156 enumerator_t *enumerator;
157 identification_t *id;
158 reauth_data_t *data;
159 void *key;
160
161 enumerator = this->permanent->create_enumerator(this->permanent);
162 while (enumerator->enumerate(enumerator, &key, &id))
163 {
164 id->destroy(id);
165 }
166 enumerator->destroy(enumerator);
167
168 enumerator = this->reauth->create_enumerator(this->reauth);
169 while (enumerator->enumerate(enumerator, &key, &data))
170 {
171 data->id->destroy(data->id);
172 free(data);
173 }
174 enumerator->destroy(enumerator);
175
176 this->permanent->destroy(this->permanent);
177 this->reauth->destroy(this->reauth);
178 this->rng->destroy(this->rng);
179 free(this);
180 }
181
182 /**
183 * See header
184 */
185 eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create()
186 {
187 private_eap_simaka_reauth_provider_t *this = malloc_thing(private_eap_simaka_reauth_provider_t);
188
189 this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
190 this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
191 this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
192 this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
193 this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
194 this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth;
195 this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))gen_reauth;
196 this->public.destroy = (void(*)(eap_simaka_reauth_provider_t*))destroy;
197
198 this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
199 if (!this->rng)
200 {
201 free(this);
202 return NULL;
203 }
204 this->permanent = hashtable_create((void*)hash, (void*)equals, 0);
205 this->reauth = hashtable_create((void*)hash, (void*)equals, 0);
206
207 return &this->public;
208 }
209