Moving charon to libcharon.
[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 /**
65 * Implementation of sim_provider_t.is_pseudonym
66 */
67 static identification_t* is_pseudonym(
68 private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
69 {
70 identification_t *permanent;
71
72 permanent = this->permanent->get(this->permanent, id);
73 if (permanent)
74 {
75 return permanent->clone(permanent);
76 }
77 return NULL;
78 }
79
80 /**
81 * Generate a random identity
82 */
83 static identification_t *gen_identity(
84 private_eap_simaka_pseudonym_provider_t *this)
85 {
86 char buf[8], hex[sizeof(buf) * 2 + 1];
87
88 this->rng->get_bytes(this->rng, sizeof(buf), buf);
89 chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE);
90
91 return identification_create_from_string(hex);
92 }
93
94 /**
95 * Implementation of sim_provider_t.get_pseudonym
96 */
97 static identification_t* gen_pseudonym(
98 private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
99 {
100 identification_t *pseudonym, *permanent;
101
102 /* remove old entry */
103 pseudonym = this->pseudonym->remove(this->pseudonym, id);
104 if (pseudonym)
105 {
106 permanent = this->permanent->remove(this->permanent, pseudonym);
107 if (permanent)
108 {
109 permanent->destroy(permanent);
110 }
111 pseudonym->destroy(pseudonym);
112 }
113
114 pseudonym = gen_identity(this);
115
116 /* create new entries */
117 id = id->clone(id);
118 this->pseudonym->put(this->pseudonym, id, pseudonym);
119 this->permanent->put(this->permanent, pseudonym, id);
120
121 return pseudonym->clone(pseudonym);
122 }
123
124 /**
125 * Implementation of eap_simaka_pseudonym_provider_t.destroy.
126 */
127 static void destroy(private_eap_simaka_pseudonym_provider_t *this)
128 {
129 enumerator_t *enumerator;
130 identification_t *id;
131 void *key;
132
133 enumerator = this->pseudonym->create_enumerator(this->pseudonym);
134 while (enumerator->enumerate(enumerator, &key, &id))
135 {
136 id->destroy(id);
137 }
138 enumerator->destroy(enumerator);
139
140 enumerator = this->permanent->create_enumerator(this->permanent);
141 while (enumerator->enumerate(enumerator, &key, &id))
142 {
143 id->destroy(id);
144 }
145 enumerator->destroy(enumerator);
146
147 this->pseudonym->destroy(this->pseudonym);
148 this->permanent->destroy(this->permanent);
149 this->rng->destroy(this->rng);
150 free(this);
151 }
152
153 /**
154 * See header
155 */
156 eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create()
157 {
158 private_eap_simaka_pseudonym_provider_t *this;
159
160 this = malloc_thing(private_eap_simaka_pseudonym_provider_t);
161
162 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;
163 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;
164 this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
165 this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym;
166 this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym;
167 this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
168 this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null;
169 this->public.destroy = (void(*)(eap_simaka_pseudonym_provider_t*))destroy;
170
171 this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
172 if (!this->rng)
173 {
174 free(this);
175 return NULL;
176 }
177 this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0);
178 this->permanent = hashtable_create((void*)hash, (void*)equals, 0);
179
180 return &this->public;
181 }
182