aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/gnunet/identity/Identity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/gnunet/identity/Identity.java')
-rw-r--r--src/main/java/org/gnunet/identity/Identity.java344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/main/java/org/gnunet/identity/Identity.java b/src/main/java/org/gnunet/identity/Identity.java
new file mode 100644
index 0000000..657a0b9
--- /dev/null
+++ b/src/main/java/org/gnunet/identity/Identity.java
@@ -0,0 +1,344 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.identity;
22
23
24import com.google.common.collect.Lists;
25import org.gnunet.identity.messages.*;
26import org.gnunet.mq.Envelope;
27import org.gnunet.requests.RequestContainer;
28import org.gnunet.requests.SequentialRequestContainer;
29import org.gnunet.util.*;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import java.util.List;
34
35public class Identity {
36 private static final Logger logger = LoggerFactory
37 .getLogger(Identity.class);
38 private Configuration configuration;
39 private SequentialRequestContainer<IdentityRequest> requests;
40 private Client client;
41 private IdentityListCallback identityListCallback;
42 private List<Ego> knownEgos = Lists.newLinkedList();
43
44 private static Ego anonymousEgo;
45
46 public static class Ego {
47 private String name;
48 private CryptoECC.PrivateKey privateKey;
49
50 public Ego(String egoName, CryptoECC.PrivateKey privateKey) {
51 this.name = egoName;
52 this.privateKey = privateKey;
53 }
54 public CryptoECC.PrivateKey getPrivateKey() {
55 return privateKey;
56 }
57 public CryptoECC.PublicSignKey getPublicKey() {
58 return CryptoECC.computePublicKey(privateKey);
59 }
60 public String getName() {
61 return name;
62 }
63 }
64
65 public abstract class IdentityRequest extends RequestContainer.Request {
66
67 public void onError(String errorMessage) {
68 throw new AssertionError("unexpected error message: " + errorMessage);
69 }
70
71 public void onResult() {
72 throw new AssertionError("unexpected result");
73 }
74 }
75
76 public class GetDefaultRequest extends IdentityRequest {
77 IdentityCallback identityCallback;
78 String serviceName;
79 GetDefaultRequest(String serviceName, IdentityCallback identityCallback) {
80 this.identityCallback = identityCallback;
81 this.serviceName = serviceName;
82 }
83 @Override
84 public Envelope assembleRequest() {
85 GetDefaultMessage m = new GetDefaultMessage();
86 m.nameLength = serviceName.length() + 1;
87 m.serviceName = serviceName;
88 return new Envelope(m);
89 }
90
91 @Override
92 public void onError(String errorMessage) {
93 identityCallback.onError(errorMessage);
94 }
95 }
96
97 public class SetDefaultRequest extends IdentityRequest {
98 IdentityContinuation cont;
99 String serviceName;
100 Ego ego;
101 SetDefaultRequest(String serviceName, Ego ego) {
102 this.serviceName = serviceName;
103 this.ego = ego;
104 }
105 @Override
106 public Envelope assembleRequest() {
107 SetDefaultMessage m = new SetDefaultMessage();
108 m.nameLength = serviceName.length() + 1;
109 m.serviceName = serviceName;
110 m.privateKey = ego.privateKey;
111 return new Envelope(m);
112 }
113 @Override
114 public void onError(String errorMessage) {
115 cont.onError(errorMessage);
116 }
117 @Override
118 public void onResult() {
119 cont.onDone();
120 }
121 }
122
123 public class RenameRequest extends IdentityRequest {
124 IdentityContinuation cont;
125 String oldName;
126 String newName;
127 RenameRequest(String newName, String oldName) {
128 this.oldName = oldName;
129 this.newName = newName;
130 }
131 @Override
132 public Envelope assembleRequest() {
133 RenameMessage m = new RenameMessage();
134 m.newName = newName;
135 m.newNameLength = newName.length() + 1;
136 m.oldName = oldName;
137 m.oldNameLength = oldName.length() + 1;
138 return new Envelope(m);
139 }
140 @Override
141 public void onError(String errorMessage) {
142 cont.onError(errorMessage);
143 }
144 @Override
145 public void onResult() {
146 cont.onDone();
147 }
148 }
149
150 public class DeleteRequest extends IdentityRequest {
151 IdentityContinuation cont;
152 String name;
153 DeleteRequest(String name) {
154 this.name = name;
155 }
156 @Override
157 public Envelope assembleRequest() {
158 DeleteMessage m = new DeleteMessage();
159 m.name = name;
160 m.nameLength = name.length() + 1;
161 return new Envelope(m);
162 }
163 @Override
164 public void onError(String errorMessage) {
165 cont.onError(errorMessage);
166 }
167 @Override
168 public void onResult() {
169 cont.onDone();
170 }
171 }
172
173 public class CreateRequest extends IdentityRequest {
174 final CryptoECC.PrivateKey privateKey;
175 IdentityContinuation cont;
176 String name;
177 CreateRequest(String name, CryptoECC.PrivateKey privateKey, IdentityContinuation cont) {
178 this.cont = cont;
179 this.privateKey = privateKey;
180 this.name = name;
181 }
182 @Override
183 public Envelope assembleRequest() {
184 CreateRequestMessage m = new CreateRequestMessage();
185 m.name = name;
186 m.nameLength = name.length() + 1;
187 m.privateKey = privateKey;
188 return new Envelope(m);
189 }
190 @Override
191 public void onError(String errorMessage) {
192 cont.onError(errorMessage);
193 }
194
195 @Override
196 public void onResult() {
197 cont.onDone();
198 }
199 }
200
201 public static Ego getAnonymousEgo() {
202 if (anonymousEgo == null) {
203 anonymousEgo = new Ego(null, CryptoECC.getAnonymous());
204 }
205 return anonymousEgo;
206 }
207
208
209 public Identity() {
210 // do nothing
211 }
212
213 public void connect(Configuration configuration, IdentityListCallback identityListCallback) {
214 this.configuration = configuration;
215 this.client = new Client("identity", configuration);
216 this.client.installReceiver(new IdentityReceiver());
217 requests = new SequentialRequestContainer<IdentityRequest>(this.client);
218 this.identityListCallback = identityListCallback;
219 StartMessage m = new StartMessage();
220 client.send(m);
221 }
222
223 public Cancelable get(String serviceName, IdentityCallback identityCallback) {
224 return requests.addRequest(new GetDefaultRequest(serviceName, identityCallback));
225 }
226
227 /**
228 * Set the default ego for a service.
229 *
230 * @param serviceName service
231 * @param ego ego
232 * @return object for cancellation
233 */
234 public Cancelable set(String serviceName, Ego ego) {
235 return requests.addRequest(new SetDefaultRequest(serviceName, ego));
236 }
237
238 public void disconnect() {
239 client.disconnect();
240 client = null;
241 }
242
243 /**
244 * Create a new ego with the given name.
245 *
246 * @param name ego name
247 * @param cont continuation
248 * @return object for cancellation
249 */
250 public Cancelable create(String name, IdentityContinuation cont) {
251 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.createRandom();
252 return requests.addRequest(new CreateRequest(name, privateKey, cont));
253 }
254
255 /**
256 * Rename an ego.
257 *
258 * @param oldName old name of the ego
259 * @param newName new name of the ego
260 * @return object for cancellation
261 */
262 public Cancelable rename(String oldName, String newName) {
263 return requests.addRequest(new RenameRequest(newName, oldName));
264 }
265
266 /**
267 * Delete an ego.
268 *
269 * @param name name of the ego to delete
270 * @return object for cancellation
271 */
272 public Cancelable delete(String name) {
273 return requests.addRequest(new DeleteRequest(name));
274 }
275
276 private Ego getEgoForKey(CryptoECC.PrivateKey privateKey) {
277 for (Ego ex : knownEgos) {
278 if (ex.privateKey.equals(privateKey)) {
279 return ex;
280 }
281 }
282 return null;
283 }
284
285 public class IdentityReceiver extends RunaboutMessageReceiver {
286 @Override
287 public void handleError() {
288 logger.warn("identity service disconnected");
289 client.reconnect();
290 }
291
292 public void visit(ResultCodeMessage m) {
293 IdentityRequest r = requests.getRequest();
294 if (null == r) {
295 logger.warn("unsolicited result code message");
296 return;
297 }
298 if (m.errorMessage != null) {
299 r.onError(m.errorMessage);
300 } else {
301 r.onResult();
302 }
303 requests.next();
304 }
305
306 public void visit(SetDefaultMessage m) {
307 IdentityRequest r = requests.getRequest();
308 if (!(r instanceof GetDefaultRequest)) {
309 logger.error("unexpected 'default ego' response");
310 return;
311 }
312 GetDefaultRequest gdr = (GetDefaultRequest) r;
313 Ego ego = getEgoForKey(m.privateKey);
314 if (null != ego)
315 gdr.identityCallback.onEgo(ego);
316 }
317
318 public void visit(final UpdateListMessage m) {
319 if (m.endOfList != 0) {
320 identityListCallback.onListEnd();
321 return;
322 }
323 if (m.nameLength == 0) {
324 Ego e = getEgoForKey(m.privateKey);
325 if (null != e) {
326 knownEgos.remove(e);
327 }
328 identityListCallback.onEgoDelete(e);
329 } else {
330 Ego existingEgo = getEgoForKey(m.privateKey);
331 if (existingEgo == null) {
332 Ego ego = new Ego(m.egoName, m.privateKey);
333 knownEgos.add(ego);
334 identityListCallback.onEgoAdd(ego);
335 } else {
336 // rename
337 String oldName = existingEgo.name;
338 existingEgo.name = m.egoName;
339 identityListCallback.onEgoRename(oldName, existingEgo);
340 }
341 }
342 }
343 }
344}