From 31621bb353138c8c5db7f54c103f513bba2e28d1 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 4 Sep 2013 11:20:04 +0000 Subject: - blacklist is now has its own handle - mesh fixed and tested - voting template - Ed25519+ecdh implemented and tested --- src/main/java/org/gnunet/construct/MsgMap.txt | 46 --- .../java/org/gnunet/construct/ReflectUtil.java | 11 +- .../gnunet/construct/parsers/IntegerParser.java | 14 +- src/main/java/org/gnunet/core/Core.java | 18 ++ .../org/gnunet/core/PeerIdentityContinuation.java | 7 + src/main/java/org/gnunet/mesh/DataMessage.java | 4 +- src/main/java/org/gnunet/mesh/LocalAckMessage.java | 4 +- src/main/java/org/gnunet/mesh/Mesh.java | 50 ++- .../java/org/gnunet/mesh/TunnelCreateMessage.java | 2 +- .../java/org/gnunet/mesh/TunnelDestroyMessage.java | 13 +- src/main/java/org/gnunet/mq/MessageQueue.java | 68 ++-- src/main/java/org/gnunet/testbed/Controller.java | 2 - .../java/org/gnunet/testbed/ControllerProc.java | 27 +- .../java/org/gnunet/testing/TestingSubsystem.java | 9 +- .../gnunet/transport/AddressIterateMessage.java | 3 +- src/main/java/org/gnunet/transport/Blacklist.java | 55 ++++ .../org/gnunet/transport/BlacklistCallback.java | 12 - .../gnunet/transport/BlacklistQueryMessage.java | 16 + .../gnunet/transport/BlacklistReplyMessage.java | 16 + src/main/java/org/gnunet/transport/Transport.java | 27 -- src/main/java/org/gnunet/util/Client.java | 5 + src/main/java/org/gnunet/util/Connection.java | 5 +- src/main/java/org/gnunet/util/CryptoECC.java | 360 +++++++++++++++++++++ src/main/java/org/gnunet/util/Helper.java | 35 +- src/main/java/org/gnunet/util/Scheduler.java | 20 +- src/main/resources/org/gnunet/construct/MsgMap.txt | 43 +-- .../resources/org/gnunet/voting/template.espec | 36 +++ .../java/org/gnunet/construct/ConstructTest.java | 20 ++ src/test/java/org/gnunet/mesh/MeshTest.java | 46 ++- src/test/java/org/gnunet/testbed/TestbedTest.java | 41 +++ src/test/java/org/gnunet/util/CryptoECCTest.java | 82 +++++ 31 files changed, 893 insertions(+), 204 deletions(-) delete mode 100644 src/main/java/org/gnunet/construct/MsgMap.txt create mode 100644 src/main/java/org/gnunet/core/PeerIdentityContinuation.java create mode 100644 src/main/java/org/gnunet/transport/Blacklist.java delete mode 100644 src/main/java/org/gnunet/transport/BlacklistCallback.java create mode 100644 src/main/java/org/gnunet/transport/BlacklistQueryMessage.java create mode 100644 src/main/java/org/gnunet/transport/BlacklistReplyMessage.java create mode 100644 src/main/java/org/gnunet/util/CryptoECC.java create mode 100644 src/main/resources/org/gnunet/voting/template.espec create mode 100644 src/test/java/org/gnunet/testbed/TestbedTest.java create mode 100644 src/test/java/org/gnunet/util/CryptoECCTest.java (limited to 'src') diff --git a/src/main/java/org/gnunet/construct/MsgMap.txt b/src/main/java/org/gnunet/construct/MsgMap.txt deleted file mode 100644 index 30a4656..0000000 --- a/src/main/java/org/gnunet/construct/MsgMap.txt +++ /dev/null @@ -1,46 +0,0 @@ -org.gnunet.util.Resolver$Address|0=org.gnunet.util.Resolver$TextualAddress -org.gnunet.util.Resolver$Address|1=org.gnunet.util.Resolver$NumericAddress -org.gnunet.util.GnunetMessage$Body|68=org.gnunet.core.DisconnectNotifyMessage -org.gnunet.util.GnunetMessage$Body|274=org.gnunet.mesh.TunnelDestroyMessage -org.gnunet.util.GnunetMessage$Body|1=org.gnunet.util.TestMessage -org.gnunet.util.GnunetMessage$Body|70=org.gnunet.core.NotifyInboundTrafficMessage -org.gnunet.util.GnunetMessage$Body|273=org.gnunet.mesh.TunnelCreateMessage -org.gnunet.util.GnunetMessage$Body|71=org.gnunet.core.NotifyOutboundTrafficMessage -org.gnunet.util.GnunetMessage$Body|272=org.gnunet.mesh.ClientConnectMessage -org.gnunet.util.GnunetMessage$Body|64=org.gnunet.core.InitMessage -org.gnunet.util.GnunetMessage$Body|4=org.gnunet.util.Resolver$GetMessage -org.gnunet.util.GnunetMessage$Body|65=org.gnunet.core.InitReplyMessage -org.gnunet.util.GnunetMessage$Body|5=org.gnunet.util.Resolver$ResolverResponse -org.gnunet.util.GnunetMessage$Body|143=org.gnunet.dht.ClientGetMessage -org.gnunet.util.GnunetMessage$Body|67=org.gnunet.core.ConnectNotifyMessage -org.gnunet.util.GnunetMessage$Body|142=org.gnunet.dht.ClientPutMessage -org.gnunet.util.GnunetMessage$Body|76=org.gnunet.core.SendMessage -org.gnunet.util.GnunetMessage$Body|286=org.gnunet.mesh.LocalAckMessage -org.gnunet.util.GnunetMessage$Body|74=org.gnunet.core.SendMessageRequest -org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady -org.gnunet.util.GnunetMessage$Body|153=org.gnunet.dht.MonitorStartStop -org.gnunet.util.GnunetMessage$Body|155=org.gnunet.dht.ClientPutConfirmationMessage -org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.UpdateMessage -org.gnunet.util.GnunetMessage$Body|260=org.gnunet.mesh.DataMessage -org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.StartMessage -org.gnunet.util.GnunetMessage$Body|144=org.gnunet.dht.ClientGetStopMessage -org.gnunet.util.GnunetMessage$Body|145=org.gnunet.dht.ClientResultMessage -org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage -org.gnunet.util.GnunetMessage$Body|333=org.gnunet.peerinfo.InfoEnd -org.gnunet.util.GnunetMessage$Body|149=org.gnunet.dht.MonitorGetMessage -org.gnunet.util.GnunetMessage$Body|331=org.gnunet.peerinfo.ListAllPeersMessage -org.gnunet.util.GnunetMessage$Body|150=org.gnunet.dht.MonitorGetRespMessage -org.gnunet.util.GnunetMessage$Body|151=org.gnunet.dht.MonitorPutMessage -org.gnunet.util.GnunetMessage$Body|171=org.gnunet.statistics.GetResponseEndMessage -org.gnunet.util.GnunetMessage$Body|170=org.gnunet.statistics.GetResponseMessage -org.gnunet.util.GnunetMessage$Body|169=org.gnunet.statistics.GetMessage -org.gnunet.util.GnunetMessage$Body|168=org.gnunet.statistics.SetMessage -org.gnunet.util.GnunetMessage$Body|374=org.gnunet.transport.RequestConnectMessage -org.gnunet.util.GnunetMessage$Body|173=org.gnunet.statistics.WatchResponseMessage -org.gnunet.util.GnunetMessage$Body|172=org.gnunet.statistics.WatchMessage -org.gnunet.util.GnunetMessage$Body|524=org.gnunet.consensus.ConcludeMessage -org.gnunet.util.GnunetMessage$Body|521=org.gnunet.consensus.InsertElementMessage -org.gnunet.util.GnunetMessage$Body|523=org.gnunet.consensus.NewElementMessage -org.gnunet.util.GnunetMessage$Body|360=org.gnunet.transport.StartMessage -org.gnunet.construct.MessageUnion|525=org.gnunet.consensus.ConcludeDoneMessage -# generated 2013/08/22 21:14:59 diff --git a/src/main/java/org/gnunet/construct/ReflectUtil.java b/src/main/java/org/gnunet/construct/ReflectUtil.java index 1115641..b05a829 100644 --- a/src/main/java/org/gnunet/construct/ReflectUtil.java +++ b/src/main/java/org/gnunet/construct/ReflectUtil.java @@ -78,7 +78,7 @@ public class ReflectUtil { * An enumeration of all built-in type that can store integers. */ public enum NumFieldType { - BIGNUM, BYTE_PRIM, SHORT_PRIM, INT_PRIM, LONG_PRIM, CHAR_PRIM + BIGNUM, BYTE_PRIM, SHORT_PRIM, INT_PRIM, LONG_PRIM, BOOLEAN, CHAR_PRIM } /** @@ -107,6 +107,8 @@ public class ReflectUtil { targetType = NumFieldType.CHAR_PRIM; } else if (f.getType().equals(BigInteger.class)) { targetType = NumFieldType.BIGNUM; + } else if (f.getType().equals(Boolean.TYPE)) { + targetType = NumFieldType.BOOLEAN; } else { throw new AssertionError( "expected numeric type, got: " + f.getType()); @@ -134,6 +136,9 @@ public class ReflectUtil { case BIGNUM: targetField.set(obj, BigInteger.valueOf(val)); break; + case BOOLEAN: + targetField.setBoolean(obj, (val != 0)); + break; } } catch (IllegalArgumentException e) { throw new AssertionError("cannot access field"); @@ -163,8 +168,10 @@ public class ReflectUtil { return targetField.getByte(obj); case CHAR_PRIM: return targetField.getChar(obj); + case BOOLEAN: + return targetField.getBoolean(obj) ? 1 : 0; case BIGNUM: - throw new RuntimeException("get() called on NumField that is a BigInteger"); + throw new RuntimeException("get() called on NumField that is a BigInteger (getBig() must be used instead)"); default: throw new AssertionError("unreachable"); } diff --git a/src/main/java/org/gnunet/construct/parsers/IntegerParser.java b/src/main/java/org/gnunet/construct/parsers/IntegerParser.java index 4f71aa5..e991f41 100644 --- a/src/main/java/org/gnunet/construct/parsers/IntegerParser.java +++ b/src/main/java/org/gnunet/construct/parsers/IntegerParser.java @@ -21,9 +21,11 @@ package org.gnunet.construct.parsers; import org.gnunet.construct.Message; +import org.gnunet.construct.ProtocolViolationException; import org.gnunet.construct.ReflectUtil; import java.lang.reflect.Field; +import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.List; @@ -59,10 +61,14 @@ public class IntegerParser implements Parser { @Override public int parse(final ByteBuffer srcBuf, int frameOffset, Message frameObj, final Message dstObj, List frameSizePath) { - if (targetField.isBig()) { - targetField.set(dstObj, IntegerUtil.readBigInteger(srcBuf, isSigned, byteSize)); - } else { - targetField.set(dstObj, IntegerUtil.readLong(srcBuf, isSigned, byteSize)); + try { + if (targetField.isBig()) { + targetField.set(dstObj, IntegerUtil.readBigInteger(srcBuf, isSigned, byteSize)); + } else { + targetField.set(dstObj, IntegerUtil.readLong(srcBuf, isSigned, byteSize)); + } + } catch (BufferUnderflowException e) { + throw new ProtocolViolationException("Underflow while parsing " + targetField); } return byteSize; } diff --git a/src/main/java/org/gnunet/core/Core.java b/src/main/java/org/gnunet/core/Core.java index 2895e41..02756db 100644 --- a/src/main/java/org/gnunet/core/Core.java +++ b/src/main/java/org/gnunet/core/Core.java @@ -291,6 +291,24 @@ public class Core { return ntr_requests.addRequest(rid, notifyRequest); } + /** + * Helper function to retrieve the peer identity with the given configuration via CORE. + * Should not be used unless there is no other means to obtain the peer identity. + * + * @param cfg + * @param cont + */ + public static void withPeerIdentity(Configuration cfg, final PeerIdentityContinuation cont) { + final Core core = new Core(cfg); + core.init(new InitCallback() { + @Override + public void onInit(PeerIdentity myIdentity) { + core.disconnect(); + cont.cont(myIdentity); + } + }); + } + /** * Observe outgoing message headers from core. * @param h callback diff --git a/src/main/java/org/gnunet/core/PeerIdentityContinuation.java b/src/main/java/org/gnunet/core/PeerIdentityContinuation.java new file mode 100644 index 0000000..e29af45 --- /dev/null +++ b/src/main/java/org/gnunet/core/PeerIdentityContinuation.java @@ -0,0 +1,7 @@ +package org.gnunet.core; + +import org.gnunet.util.PeerIdentity; + +public interface PeerIdentityContinuation { + public void cont(PeerIdentity peerIdentity); +} diff --git a/src/main/java/org/gnunet/mesh/DataMessage.java b/src/main/java/org/gnunet/mesh/DataMessage.java index 92546c8..a5ced12 100644 --- a/src/main/java/org/gnunet/mesh/DataMessage.java +++ b/src/main/java/org/gnunet/mesh/DataMessage.java @@ -9,10 +9,10 @@ import org.gnunet.util.PeerIdentity; * * @author Florian Dold */ -@UnionCase(260) +@UnionCase(285) public class DataMessage implements GnunetMessage.Body { @UInt32 - public int tid; + public long tid; @FillWith @UInt8 public byte[] payload; diff --git a/src/main/java/org/gnunet/mesh/LocalAckMessage.java b/src/main/java/org/gnunet/mesh/LocalAckMessage.java index 6a09411..4466009 100644 --- a/src/main/java/org/gnunet/mesh/LocalAckMessage.java +++ b/src/main/java/org/gnunet/mesh/LocalAckMessage.java @@ -12,7 +12,5 @@ import org.gnunet.util.GnunetMessage; @UnionCase(286) public class LocalAckMessage implements GnunetMessage.Body { @UInt32 - public int tid; - @UInt32 - public int maxPid; + public long tid; } diff --git a/src/main/java/org/gnunet/mesh/Mesh.java b/src/main/java/org/gnunet/mesh/Mesh.java index a6bf602..b66cc6f 100644 --- a/src/main/java/org/gnunet/mesh/Mesh.java +++ b/src/main/java/org/gnunet/mesh/Mesh.java @@ -47,13 +47,13 @@ public class Mesh { * For tunnels created by the client, the bit in this * mask is always set. */ - private static final int TUNNEL_ID_CLI = 0x80000000; + private static final long TUNNEL_ID_CLI = 0x80000000L; /** * For tunnels created by the server, the bit in this * mask is always set. */ - private static final int TUNNEL_ID_SERV = 0xB0000000; + private static final long TUNNEL_ID_SERV = 0xB0000000L; /** * Disable buffering on intermediate nodes (for minimum latency). @@ -96,13 +96,13 @@ public class Mesh { /** * Mapping from the tunnel's ID to the tunnel object. */ - private Map tunnelMap = new HashMap(); + private Map tunnelMap = new HashMap(); /** * Counter for generating fresh tunnel ID's * when creating new tunnels. */ - private int next_tid = 1; + private long next_tid = 1; /** * A tunnel to a remote peer. @@ -113,9 +113,9 @@ public class Mesh { private final int opt; public final PeerIdentity peer; public final int port; - protected int tunnelId; + protected long tunnelId; private boolean receive_done_expected = false; - int ack_count = 1; + int ack_count = 0; /** * Canceler for the currently submitted envelope. @@ -153,19 +153,25 @@ public class Mesh { * @param nobuffer * @param reliable */ - public Tunnel(PeerIdentity peer, int tunnelId, int port, boolean nobuffer, boolean reliable) { + public Tunnel(PeerIdentity peer, long tunnelId, int port, boolean nobuffer, boolean reliable) { int my_opt = 0; if (reliable) my_opt |= OPTION_RELIABLE; if (nobuffer) my_opt |= OPTION_NOBUFFER; - if (0 == tunnelId) - this.tunnelId = ((next_tid++) | TUNNEL_ID_CLI) & ~TUNNEL_ID_SERV; - else + if (0 == tunnelId) { + this.tunnelId = next_tid++; + this.tunnelId &= ~TUNNEL_ID_SERV; + this.tunnelId |= TUNNEL_ID_CLI; + } + else { this.tunnelId = tunnelId; + } this.peer = peer; this.port = port; this.opt = my_opt; + logger.debug("registering tunnel {}", this.tunnelId); + tunnelMap.put(this.tunnelId, this); } public void receiveDone() { @@ -180,20 +186,24 @@ public class Mesh { public void destroy() { TunnelDestroyMessage m = new TunnelDestroyMessage(); m.tunnel_id = tunnelId; + m.reserved = new byte[32]; client.send(m); + tunnelMap.remove(m.tunnel_id); } @Override protected void submit(Envelope ev) { + logger.debug("submitting data message on tunnel {}", tunnelId); if (ack_count <= 0) throw new AssertionError(); DataMessage m = new DataMessage(); m.payload = Construct.toBinary(GnunetMessage.fromBody(ev.message)); + m.tid = tunnelId; Envelope mesh_ev = new Envelope(m); mesh_ev.notifySent(new NotifySentHandler() { @Override public void onSent() { - envelopeCanceler = null; + envelopeCanceler = null; reportMessageSent(); } }); client.send(mesh_ev); @@ -217,12 +227,20 @@ public class Mesh { context = newContext; } + public void handleAck() { + ack_count++; + logger.debug("got ack for tunnel id " + tunnelId); + if (ack_count == 1) { + reportReadyForSubmit(); + } + } } private class MeshMessageReceiver extends RunaboutMessageReceiver { public void visit(TunnelCreateMessage m) { Tunnel t = new Tunnel(m.otherEnd, m.tunnel_id, m.port, (m.opt & OPTION_NOBUFFER) != 0, (m.opt & OPTION_NOBUFFER) != 0); + logger.debug("inbound tunnel {}", m.tunnel_id); if (inboundTunnelHandler != null) { inboundTunnelHandler.onInboundTunnel(t, m.otherEnd); } @@ -240,9 +258,13 @@ public class Mesh { } public void visit(LocalAckMessage m) { + logger.debug("got LocalAckMessage for {}", m.tid); Tunnel t = tunnelMap.get(m.tid); - if (t != null) - t.ack_count += 1; + if (t != null) { + t.handleAck(); + } else { + logger.warn("tunnel id for local ack not found"); + } } public void visit(TunnelDestroyMessage m) { @@ -286,6 +308,8 @@ public class Mesh { this.ports = ports; this.inboundTunnelHandler = inboundTunnelHandler; + logger.debug("mesh handle created"); + client = new Client("mesh", cfg); client.installReceiver(new MeshMessageReceiver()); ClientConnectMessage ccm = new ClientConnectMessage(); diff --git a/src/main/java/org/gnunet/mesh/TunnelCreateMessage.java b/src/main/java/org/gnunet/mesh/TunnelCreateMessage.java index eaa4d6c..84ea035 100644 --- a/src/main/java/org/gnunet/mesh/TunnelCreateMessage.java +++ b/src/main/java/org/gnunet/mesh/TunnelCreateMessage.java @@ -14,7 +14,7 @@ import org.gnunet.util.PeerIdentity; @UnionCase(273) public class TunnelCreateMessage implements GnunetMessage.Body { @UInt32 - public int tunnel_id; + public long tunnel_id; @NestedMessage(optional = false) public PeerIdentity otherEnd; diff --git a/src/main/java/org/gnunet/mesh/TunnelDestroyMessage.java b/src/main/java/org/gnunet/mesh/TunnelDestroyMessage.java index bce60bb..3fa973f 100644 --- a/src/main/java/org/gnunet/mesh/TunnelDestroyMessage.java +++ b/src/main/java/org/gnunet/mesh/TunnelDestroyMessage.java @@ -1,8 +1,11 @@ package org.gnunet.mesh; +import org.gnunet.construct.FixedSizeIntegerArray; +import org.gnunet.construct.NestedMessage; import org.gnunet.construct.UInt32; import org.gnunet.construct.UnionCase; import org.gnunet.util.GnunetMessage; +import org.gnunet.util.PeerIdentity; /** * ... @@ -12,5 +15,13 @@ import org.gnunet.util.GnunetMessage; @UnionCase(274) public class TunnelDestroyMessage implements GnunetMessage.Body { @UInt32 - public int tunnel_id; + public long tunnel_id; + + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] reserved; + @UInt32 + public int port; + + @UInt32 + public int opt; } diff --git a/src/main/java/org/gnunet/mq/MessageQueue.java b/src/main/java/org/gnunet/mq/MessageQueue.java index 4df3ae4..cab1003 100644 --- a/src/main/java/org/gnunet/mq/MessageQueue.java +++ b/src/main/java/org/gnunet/mq/MessageQueue.java @@ -11,10 +11,19 @@ import java.util.LinkedList; public abstract class MessageQueue { private LinkedList queued_envelopes = new LinkedList(); private LinkedList prefered_queued_envelopes = new LinkedList(); - protected Envelope current_envelope; + protected Envelope currentEnvelope; + private boolean readyForSubmit; + /** + * Submit a message. Once the message can't be canceled, + * reportMessageSent must be called. + * @param ev envelope to submit + */ protected abstract void submit(Envelope ev); + /** + * Cancel a message that already has been submitted. + */ protected abstract void retract(); public void send(GnunetMessage.Body body) { @@ -25,6 +34,16 @@ public abstract class MessageQueue { sendPrefered(new Envelope(body)); } + public void send(Envelope ev) { + queued_envelopes.addLast(ev); + trySubmitNext(); + } + + public void sendPrefered(Envelope ev) { + prefered_queued_envelopes.addLast(ev); + trySubmitNext(); + } + private Envelope pollNextEnvelope() { if (!prefered_queued_envelopes.isEmpty()) return prefered_queued_envelopes.removeFirst(); @@ -33,36 +52,33 @@ public abstract class MessageQueue { return null; } - public void send(Envelope ev) { - if (null == current_envelope) { - current_envelope = ev; - submit(current_envelope); - } else { - queued_envelopes.addLast(ev); + protected void trySubmitNext() { + if (currentEnvelope != null || !readyForSubmit) { + return; + } + Envelope ev = pollNextEnvelope(); + if (ev == null) { + return; } + currentEnvelope = ev; + readyForSubmit = false; + submit(currentEnvelope); } - public void sendPrefered(Envelope ev) { - if (null == current_envelope) { - current_envelope = ev; - submit(current_envelope); - } else { - prefered_queued_envelopes.addLast(ev); + protected void reportReadyForSubmit() { + if (readyForSubmit) { + throw new AssertionError("message queue reported 'ready for submit' twice"); } + readyForSubmit = true; + trySubmitNext(); } protected void reportMessageSent() { - if (null == current_envelope) + if (null == currentEnvelope) throw new AssertionError(); - current_envelope.invokeSentNotification(); - next(); - } - - private void next() { - current_envelope = pollNextEnvelope(); - if (current_envelope == null) - return; - submit(current_envelope); + currentEnvelope.invokeSentNotification(); + currentEnvelope = null; + trySubmitNext(); } /** @@ -71,11 +87,11 @@ public abstract class MessageQueue { * @param ev the envelope to cancel */ /* pkg-private */ void cancelEnvelope(Envelope ev) { - if (null == current_envelope) + if (null == currentEnvelope) throw new AssertionError(); - if (ev == current_envelope) { + if (ev == currentEnvelope) { retract(); - next(); + trySubmitNext(); } else { queued_envelopes.remove(ev); prefered_queued_envelopes.remove(ev); diff --git a/src/main/java/org/gnunet/testbed/Controller.java b/src/main/java/org/gnunet/testbed/Controller.java index 7372986..863c6fe 100644 --- a/src/main/java/org/gnunet/testbed/Controller.java +++ b/src/main/java/org/gnunet/testbed/Controller.java @@ -37,7 +37,6 @@ public class Controller { client = new Client("testbed", host.cfg); } - /** * Create the given peer at the specified host using the given * controller. If the given controller is not running on the target @@ -70,7 +69,6 @@ public class Controller { return null; } - /** * Stop the given controller (also will terminate all peers and * controllers dependent on this controller). This function diff --git a/src/main/java/org/gnunet/testbed/ControllerProc.java b/src/main/java/org/gnunet/testbed/ControllerProc.java index 9eaca2c..69961c7 100644 --- a/src/main/java/org/gnunet/testbed/ControllerProc.java +++ b/src/main/java/org/gnunet/testbed/ControllerProc.java @@ -13,19 +13,28 @@ import java.util.zip.Deflater; * the testbed helper on a remote machine. */ public class ControllerProc { - final Helper helper; + private Helper helper; public class ControllerProcReceiver extends RunaboutMessageReceiver { public void visit(HelperReplyMessage m) { + System.out.println("got controller proc message"); } + @Override public void handleError() { - + throw new AssertionError(); } } + /** + * Create a controller proc. Nothing will hapen until ControllerProc.start is called. + */ + public void ControllerProc() { + + } + /** * Starts a controller process at the given host. The given host's configration * is used as a Template configuration to use for the remote controller; the @@ -47,12 +56,22 @@ public class ControllerProc { * (synchronous errors will be signalled by returning NULL). This * parameter cannot be NULL. */ - public ControllerProc(String trustedIP, Host host, ControllerStatusCallback cb) { + public void start(String trustedIP, Host host, ControllerStatusCallback cb) { if (host.isLocal()) { - helper = new Helper(false, "gnunet-testbed-helper", null, new ControllerProcReceiver()); + helper = new Helper(false, "gnunet-helper-testbed", null, new ControllerProcReceiver()); } else { throw new AssertionError("not implemented yet"); } + helper.send(makeHelperInitMessage(trustedIP, host)); + } + + /** + * Stop the controller process (also will terminate all peers and controllers + * dependent on this controller). This function blocks until the testbed has + * been fully terminated (!). The controller status cb will not be called. + */ + public void stop() { + throw new AssertionError("not implemented"); } diff --git a/src/main/java/org/gnunet/testing/TestingSubsystem.java b/src/main/java/org/gnunet/testing/TestingSubsystem.java index da7f2e4..f36412c 100644 --- a/src/main/java/org/gnunet/testing/TestingSubsystem.java +++ b/src/main/java/org/gnunet/testing/TestingSubsystem.java @@ -85,15 +85,8 @@ public class TestingSubsystem { cfg = new Configuration(); cfg.parse(cfgFileName); - - try { - if (p.getErrorStream().available() != 0) { - throw new TestingSetup.SetupException("error starting service"); - } - } catch (IOException e) { - throw new TestingSetup.SetupException(e); - } } + public void destroy() { try { writer.write("q\n"); diff --git a/src/main/java/org/gnunet/transport/AddressIterateMessage.java b/src/main/java/org/gnunet/transport/AddressIterateMessage.java index 59ea6a8..4fd4405 100644 --- a/src/main/java/org/gnunet/transport/AddressIterateMessage.java +++ b/src/main/java/org/gnunet/transport/AddressIterateMessage.java @@ -5,6 +5,7 @@ import org.gnunet.construct.NestedMessage; import org.gnunet.construct.UInt32; import org.gnunet.construct.UnionCase; import org.gnunet.util.AbsoluteTime; +import org.gnunet.util.GnunetMessage; import org.gnunet.util.PeerIdentity; @@ -13,7 +14,7 @@ import org.gnunet.util.PeerIdentity; * asking for binary addresses known for a peer. */ @UnionCase(380) -public class AddressIterateMessage { +public class AddressIterateMessage implements GnunetMessage.Body { /** * One shot call or continous replies? */ diff --git a/src/main/java/org/gnunet/transport/Blacklist.java b/src/main/java/org/gnunet/transport/Blacklist.java new file mode 100644 index 0000000..d17858d --- /dev/null +++ b/src/main/java/org/gnunet/transport/Blacklist.java @@ -0,0 +1,55 @@ +package org.gnunet.transport; + +import org.gnunet.util.Client; +import org.gnunet.util.Configuration; +import org.gnunet.util.PeerIdentity; +import org.gnunet.util.RunaboutMessageReceiver; + +/** + * Transport blacklist. + */ +public abstract class Blacklist { + /** + * Client connecting to the transport service. + */ + private Client client; + + private final class TransportReceiver extends RunaboutMessageReceiver { + void visit(BlacklistQueryMessage m) { + boolean allowed = isAllowed(m.peer); + BlacklistReplyMessage mr = new BlacklistReplyMessage(); + mr.is_allowed = allowed; + mr.peer = m.peer; + client.send(mr); + } + + @Override + public void handleError() { + client.reconnect(); + client.send(new BlacklistInitMessage()); + } + } + + /** + * Install a blacklist callback. The service will be queried for all + * existing connections as well as any fresh connections to check if + * they are permitted. + * The blacklist is active until the Transport handle is destroyed. + * When the transport handle that installed the blacklist is destroyed, + * all hosts that were denied in the past will automatically be + * whitelisted again. This is the only way to re-enable + * connections from peers that were previously blacklisted. + */ + public Blacklist(Configuration cfg) { + client = new Client("transport", cfg); + client.send(new BlacklistInitMessage()); + client.installReceiver(new TransportReceiver()); + } + + public void destroy() { + client.disconnect(); + client = null; + } + + protected abstract boolean isAllowed(PeerIdentity peer); +} diff --git a/src/main/java/org/gnunet/transport/BlacklistCallback.java b/src/main/java/org/gnunet/transport/BlacklistCallback.java deleted file mode 100644 index b763dec..0000000 --- a/src/main/java/org/gnunet/transport/BlacklistCallback.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.gnunet.transport; - -import org.gnunet.util.PeerIdentity; - -/** - * ... - * - * @author Florian Dold - */ -public interface BlacklistCallback { - boolean isAllowed(PeerIdentity peerIdentity); -} diff --git a/src/main/java/org/gnunet/transport/BlacklistQueryMessage.java b/src/main/java/org/gnunet/transport/BlacklistQueryMessage.java new file mode 100644 index 0000000..4947dd4 --- /dev/null +++ b/src/main/java/org/gnunet/transport/BlacklistQueryMessage.java @@ -0,0 +1,16 @@ +package org.gnunet.transport; + +import org.gnunet.construct.NestedMessage; +import org.gnunet.construct.UInt32; +import org.gnunet.construct.UnionCase; +import org.gnunet.util.GnunetMessage; +import org.gnunet.util.PeerIdentity; + +@UnionCase(370) +public class BlacklistQueryMessage implements GnunetMessage.Body { + @UInt32 + public byte reserved; + + @NestedMessage + public PeerIdentity peer; +} diff --git a/src/main/java/org/gnunet/transport/BlacklistReplyMessage.java b/src/main/java/org/gnunet/transport/BlacklistReplyMessage.java new file mode 100644 index 0000000..9319c97 --- /dev/null +++ b/src/main/java/org/gnunet/transport/BlacklistReplyMessage.java @@ -0,0 +1,16 @@ +package org.gnunet.transport; + +import org.gnunet.construct.NestedMessage; +import org.gnunet.construct.UInt32; +import org.gnunet.construct.UnionCase; +import org.gnunet.util.GnunetMessage; +import org.gnunet.util.PeerIdentity; + +@UnionCase(371) +public class BlacklistReplyMessage implements GnunetMessage.Body { + @UInt32 + public boolean is_allowed; + + @NestedMessage + public PeerIdentity peer; +} diff --git a/src/main/java/org/gnunet/transport/Transport.java b/src/main/java/org/gnunet/transport/Transport.java index b9881b6..f05cee5 100644 --- a/src/main/java/org/gnunet/transport/Transport.java +++ b/src/main/java/org/gnunet/transport/Transport.java @@ -19,12 +19,6 @@ public class Transport { boolean init_requested; - /** - * Blacklist callback, null if there is no active blacklist - * for this handle. - */ - BlacklistCallback blacklistCallback; - private final class TransportReceiver extends RunaboutMessageReceiver { @Override public void handleError() { @@ -112,27 +106,6 @@ public class Transport { throw new UnsupportedOperationException(); } - /** - * Install a blacklist callback. The service will be queried for all - * existing connections as well as any fresh connections to check if - * they are permitted. - * The blacklist is active until the Transport handle is destroyed. - * When the transport handle that installed the blacklist is destroyed, - * all hosts that were denied in the past will automatically be - * whitelisted again. This is the only way to re-enable - * connections from peers that were previously blacklisted. - * - * @param blacklistCallback callback to invoke to check if connections are allowed - */ - public void blacklist(BlacklistCallback blacklistCallback) { - if (this.blacklistCallback != null) - throw new AssertionError("there is already a blacklist"); - if (blacklistCallback == null) - throw new AssertionError("blacklist callback may not be null"); - this.blacklistCallback = blacklistCallback; - client.send(new BlacklistInitMessage()); - } - /** * Return all the known addresses for a specific peer or all peers. * Returns continuously all address if one_shot is set to false diff --git a/src/main/java/org/gnunet/util/Client.java b/src/main/java/org/gnunet/util/Client.java index 18c206b..899fac8 100644 --- a/src/main/java/org/gnunet/util/Client.java +++ b/src/main/java/org/gnunet/util/Client.java @@ -121,6 +121,8 @@ public class Client extends MessageQueue { throw new Configuration.ConfigurationException(String.format("hostname of service '%s' empty", serviceName)); } reconnect(); + // we don't have to wait for any acks, but can send right away! + reportReadyForSubmit(); } /** @@ -133,6 +135,8 @@ public class Client extends MessageQueue { this.hostname = hostname; this.port = port; reconnect(); + // we don't have to wait for any acks, but can send right away! + reportReadyForSubmit(); } @@ -286,6 +290,7 @@ public class Client extends MessageQueue { public void cont(boolean success) { currentSubmit = null; reportMessageSent(); + reportReadyForSubmit(); } }); } diff --git a/src/main/java/org/gnunet/util/Connection.java b/src/main/java/org/gnunet/util/Connection.java index 1fd1458..1c569c4 100644 --- a/src/main/java/org/gnunet/util/Connection.java +++ b/src/main/java/org/gnunet/util/Connection.java @@ -214,7 +214,7 @@ public class Connection { int n = connectionChannel.read(recvBuffer); if (n == -1) { currentReceiveHelper = null; - logger.warn("lost connection to service"); + logger.warn("lost connection to service, {}", connectionChannel.socket().toString()); connectionChannel.close(); connectionChannel = null; if (Connection.this.currentTransmitHelper != null) { @@ -384,7 +384,8 @@ public class Connection { String.format("tried to send message with binary size %s but size in header %s", b.length, gm.header.messageSize)); } - logger.debug("sending message (size={},type={})", b.length, gm.header.messageType); + logger.debug("sending message (size={},type={}) over {}", + new String[] {String.valueOf(b.length), String.valueOf(gm.header.messageType), connectionChannel.socket().toString()}); if (transmitBuffer.remaining() < b.length) { ByteBuffer buf = ByteBuffer.allocate(b.length + transmitBuffer.capacity()); transmitBuffer.flip(); diff --git a/src/main/java/org/gnunet/util/CryptoECC.java b/src/main/java/org/gnunet/util/CryptoECC.java new file mode 100644 index 0000000..a3ef01e --- /dev/null +++ b/src/main/java/org/gnunet/util/CryptoECC.java @@ -0,0 +1,360 @@ +package org.gnunet.util; + +import org.gnunet.construct.FixedSizeIntegerArray; +import org.gnunet.construct.Message; +import org.gnunet.construct.ProtocolViolationException; +import org.gnunet.construct.UInt32; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Implementation of the Ed25519 public-key signature system. + * Original version written and placed into the public domain by k3d3 (https://github.com/k3d3/ed25519-java). + * See also http://ed25519.cr.yp.to/. + */ +public class CryptoECC { + + /** + * Private ECC key. + */ + public static final class PrivateKey implements Message { + /** + * Value of the private key, represents a number modulo q. + * The number is stored as little endian. + */ + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] d; + } + + /** + * Public ECC key. + */ + public static final class PublicKey implements Message { + /** + * x-coordinate of the point on the curve. + * The number is stored as little endian. + */ + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] x; + + /** + * y-coordinate of the point on the curve. + * The number is stored as little endian. + */ + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] y; + + } + + /** + * ECC Signature. + */ + public static final class Signature implements Message { + /** + * R-value of the signature. + * The number is stored as little endian. + */ + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] r; + + /** + * S-value of the signature. + * The number is stored as little endian. + */ + @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) + public byte[] s; + } + + // curve parameter b + private static final int b = 256; + // curve parameter q + private static final BigInteger q = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819949"); + // q-3 + private static final BigInteger qm2 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819947"); + // q-3 + private static final BigInteger qp3 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819952"); + private static final BigInteger l = new BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989"); + private static final BigInteger d = new BigInteger("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740"); + private static final BigInteger I = new BigInteger("19681161376707505956807079304988542015446066515923890162744021073123829784752"); + private static final BigInteger By = new BigInteger("46316835694926478169428394003475163141307993866256225615783033603165251855960"); + private static final BigInteger Bx = new BigInteger("15112221349535400772501151409588531511454012693041857206046113283949847762202"); + private static final BigInteger[] B = {Bx.mod(q),By.mod(q)}; + // 2^255 + private static final BigInteger un = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819967"); + + static final private MessageDigest sha512; + static { + try { + sha512 = MessageDigest.getInstance("SHA-512"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("SHA-512 not available"); + } + } + + /** + * Computes the multiplicative inverse of x modulo q using Euler's theorem. + * + * @param x the group element to invert + * @return the inverse of x modulo q + */ + private static BigInteger inv(BigInteger x) { + return x.modPow(qm2, q); + } + + /** + * Compute the x-component of a point on our curve from + * the y-coordinate. + * + * @param y the y-coordinate of a point + * @return the x-coordinate of the point (x,y) on the curve + */ + private static BigInteger xrecover(BigInteger y) { + BigInteger y2 = y.multiply(y); + BigInteger xx = (y2.subtract(BigInteger.ONE)).multiply(inv(d.multiply(y2).add(BigInteger.ONE))); + BigInteger x = xx.modPow(qp3.divide(BigInteger.valueOf(8)), q); + if (!x.multiply(x).subtract(xx).mod(q).equals(BigInteger.ZERO)) x = (x.multiply(I).mod(q)); + if (!x.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) x = q.subtract(x); + return x; + } + + /** + * Implements the group operation (twisted Edwards addition) on our curve. + * + * @param P a point on the curve + * @param Q another point on the curve + * @return P+Q + */ + private static BigInteger[] edwards(BigInteger[] P, BigInteger[] Q) { + BigInteger x1 = P[0]; + BigInteger y1 = P[1]; + BigInteger x2 = Q[0]; + BigInteger y2 = Q[1]; + BigInteger dtemp = d.multiply(x1).multiply(x2).multiply(y1).multiply(y2); + BigInteger x3 = ((x1.multiply(y2)).add((x2.multiply(y1)))).multiply(inv(BigInteger.ONE.add(dtemp))); + BigInteger y3 = ((y1.multiply(y2)).add((x1.multiply(x2)))).multiply(inv(BigInteger.ONE.subtract(dtemp))); + return new BigInteger[]{x3.mod(q), y3.mod(q)}; + } + + /** + * Multiply a point on the curve with a constant. + * + * @param P point on the curve + * @param e constant + * @return eP + */ + private static BigInteger[] scalarmult(BigInteger[] P, BigInteger e) { + if (e.equals(BigInteger.ZERO)) { + return new BigInteger[]{BigInteger.ZERO, BigInteger.ONE}; + } + BigInteger[] Q = scalarmult(P, e.shiftRight(1)); + Q = edwards(Q, Q); + if (e.testBit(0)) Q = edwards(Q, P); + return Q; + } + + /** + * Encode an integer to binary format. + * + * @param y integer to encode + * @return encoded integer as byte array + */ + private static byte[] encodeint(BigInteger y) { + byte[] in = y.toByteArray(); + // reverse the array + for (int i = 0; i < in.length / 2; i++) { + byte tmp = in[i]; + in[i] = in[in.length - i - 1]; + in[in.length - i - 1] = tmp; + } + return in; + } + + /** + * Encode a point to binary format. + * + * @param P point to encode + * @return encoded point as byte array + */ + private static byte[] encodepoint(BigInteger[] P) { + BigInteger x = P[0]; + BigInteger y = P[1]; + byte[] out = encodeint(y); + out[out.length-1] |= (x.testBit(0) ? 0x80 : 0); + return out; + } + + /** + * Get return the i-th bit in the given array of bytes h. + * + * @param h array of bytes + * @param i bit index + * @return i-th bit in h + */ + private static int bit(byte[] h, int i) { + return h[i/8] >> (i%8) & 1; + } + + static private BigInteger computePublicKeyCoefficient(PrivateKey sk) { + byte[] h = sha512.digest(sk.d); + BigInteger a = BigInteger.valueOf(2).pow(b-2); + for (int i=3; i < (b - 2); i++) { + BigInteger apart = BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(bit(h,i))); + a = a.add(apart); + } + return a; + } + + /** + * Derive the public key from the private key 'sk', + * + * @param sk private key + * @return public key derived from 'sk' + */ + static public PublicKey computePublicKey(PrivateKey sk) { + BigInteger a = computePublicKeyCoefficient(sk); + BigInteger[] A = scalarmult(B, a); + PublicKey publicKey = new PublicKey(); + publicKey.x = encodeint(A[0]); + publicKey.y = encodeint(A[1]); + return publicKey; + } + + /** + * Hash the data in m and return 2^h(m) + * + * @param m data to hash + * @return 2^h(m) + */ + static private BigInteger Hint(byte[] m) { + final byte[] h = sha512.digest(m); + for (int i = 0; i < 32; i++) { + byte tmp = h[i]; + h[i] = h[63 - i]; + h[63 - i] = tmp; + } + return new BigInteger(1, h); + } + + /** + * Sign a message. + * + * @param m the message to sign + * @param sk the private (secret) key + * @param pk the public key, derived from 'sk', but passed as a + * parameter for performance reasons + * @return a signature on m + */ + public static Signature sign(byte[] m, PrivateKey sk, PublicKey pk) { + byte[] compressed_pk = encodepoint(new BigInteger[]{decodeint(pk.x), decodeint(pk.y)}); + byte[] h = sha512.digest(sk.d); + BigInteger a = BigInteger.valueOf(2).pow(b-2); + for (int i = 3; i < (b - 2); i++) { + a = a.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(bit(h,i)))); + } + ByteBuffer rsub = ByteBuffer.allocate((b/8)+m.length); + rsub.put(h, b/8, b/4-b/8).put(m); + BigInteger r = Hint(rsub.array()); + BigInteger[] R = scalarmult(B,r); + + Signature sig = new Signature(); + sig.r = encodepoint(R); + + ByteBuffer buf = ByteBuffer.allocate(32 + compressed_pk.length + m.length); + buf.put(encodepoint(R)).put(compressed_pk).put(m); + + BigInteger S = r.add(Hint(buf.array()).multiply(a)).mod(l); + sig.s = encodeint(S); + + return sig; + } + + /** + * Check if a point is on the curve. + * + * @param P point to check + * @return whether the point P is on the curve + */ + private static boolean isoncurve(BigInteger[] P) { + BigInteger x = P[0]; + BigInteger y = P[1]; + BigInteger xx = x.multiply(x); + BigInteger yy = y.multiply(y); + BigInteger dxxyy = d.multiply(yy).multiply(xx); + return xx.negate().add(yy).subtract(BigInteger.ONE).subtract(dxxyy).mod(q).equals(BigInteger.ZERO); + } + + /** + * Decode an integer from its binary form. + * + * @param s the binary form if the integer + * @return the decoded integer + */ + private static BigInteger decodeint(byte[] s) { + byte[] out = new byte[s.length]; + for (int i=0;i argv, RunaboutMessageReceiver receiver) { @@ -141,7 +156,7 @@ public class Helper extends MessageQueue { if (binaryName == null) { throw new AssertionError(); } - command.add(binaryName); + command.add(getBinaryPath(binaryName)); if (argv != null) command.addAll(argv); processBuilder = new ProcessBuilder(command); @@ -150,6 +165,14 @@ public class Helper extends MessageQueue { } catch (IOException e) { throw new IOError(e); } + + writeThread = new WriteThread(); + readThread = new ReadThread(); + + writeThread.start(); + readThread.start(); + + reportReadyForSubmit(); } /** @@ -191,12 +214,14 @@ public class Helper extends MessageQueue { @Override protected void submit(Envelope ev) { + logger.debug("submitting envelope to helper thread"); synchronized (this) { if (writeMessage != null) throw new AssertionError("message queue not implemented correctly"); writeMessage = ev.message; notifyAll(); } + reportReadyForSubmit(); } @Override diff --git a/src/main/java/org/gnunet/util/Scheduler.java b/src/main/java/org/gnunet/util/Scheduler.java index 78ea288..ba7098f 100644 --- a/src/main/java/org/gnunet/util/Scheduler.java +++ b/src/main/java/org/gnunet/util/Scheduler.java @@ -44,6 +44,16 @@ public class Scheduler { // cumulative number of tasks in the ready lists private static volatile int readyCount = 0; + /** + * Priority for Tasks. + */ + public enum Priority { + IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN; + + // how many different priorities do we have? + private static final int numberOfPriorities = Priority.values().length; + } + // for every priority, there is a list of tasks that is definitely ready to run @SuppressWarnings("unchecked") final private static LinkedList[] readyLists = new LinkedList[Priority.numberOfPriorities]; @@ -107,16 +117,6 @@ public class Scheduler { } - /** - * Priority for Tasks. - */ - public enum Priority { - IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN; - - // how many different priorities do we have? - private static final int numberOfPriorities = Priority.values().length; - } - /** * Reasons for executing a task. */ diff --git a/src/main/resources/org/gnunet/construct/MsgMap.txt b/src/main/resources/org/gnunet/construct/MsgMap.txt index 2ca1246..ad2a204 100644 --- a/src/main/resources/org/gnunet/construct/MsgMap.txt +++ b/src/main/resources/org/gnunet/construct/MsgMap.txt @@ -1,46 +1,53 @@ org.gnunet.util.Resolver$Address|0=org.gnunet.util.Resolver$TextualAddress org.gnunet.util.Resolver$Address|1=org.gnunet.util.Resolver$NumericAddress -org.gnunet.util.GnunetMessage$Body|68=org.gnunet.core.DisconnectNotifyMessage -org.gnunet.util.GnunetMessage$Body|274=org.gnunet.mesh.TunnelDestroyMessage org.gnunet.util.GnunetMessage$Body|1=org.gnunet.util.TestMessage -org.gnunet.util.GnunetMessage$Body|70=org.gnunet.core.NotifyInboundTrafficMessage +org.gnunet.util.GnunetMessage$Body|274=org.gnunet.mesh.TunnelDestroyMessage org.gnunet.util.GnunetMessage$Body|273=org.gnunet.mesh.TunnelCreateMessage -org.gnunet.util.GnunetMessage$Body|71=org.gnunet.core.NotifyOutboundTrafficMessage org.gnunet.util.GnunetMessage$Body|272=org.gnunet.mesh.ClientConnectMessage -org.gnunet.util.GnunetMessage$Body|64=org.gnunet.core.InitMessage org.gnunet.util.GnunetMessage$Body|4=org.gnunet.util.Resolver$GetMessage -org.gnunet.util.GnunetMessage$Body|65=org.gnunet.core.InitReplyMessage org.gnunet.util.GnunetMessage$Body|5=org.gnunet.util.Resolver$ResolverResponse org.gnunet.util.GnunetMessage$Body|143=org.gnunet.dht.ClientGetMessage -org.gnunet.util.GnunetMessage$Body|67=org.gnunet.core.ConnectNotifyMessage org.gnunet.util.GnunetMessage$Body|142=org.gnunet.dht.ClientPutMessage -org.gnunet.util.GnunetMessage$Body|76=org.gnunet.core.SendMessage org.gnunet.util.GnunetMessage$Body|286=org.gnunet.mesh.LocalAckMessage -org.gnunet.util.GnunetMessage$Body|74=org.gnunet.core.SendMessageRequest -org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady +org.gnunet.util.GnunetMessage$Body|285=org.gnunet.mesh.DataMessage org.gnunet.util.GnunetMessage$Body|153=org.gnunet.dht.MonitorStartStop org.gnunet.util.GnunetMessage$Body|155=org.gnunet.dht.ClientPutConfirmationMessage -org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.UpdateMessage -org.gnunet.util.GnunetMessage$Body|260=org.gnunet.mesh.DataMessage -org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.StartMessage org.gnunet.util.GnunetMessage$Body|144=org.gnunet.dht.ClientGetStopMessage org.gnunet.util.GnunetMessage$Body|145=org.gnunet.dht.ClientResultMessage -org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage -org.gnunet.util.GnunetMessage$Body|333=org.gnunet.peerinfo.InfoEnd org.gnunet.util.GnunetMessage$Body|149=org.gnunet.dht.MonitorGetMessage -org.gnunet.util.GnunetMessage$Body|331=org.gnunet.peerinfo.ListAllPeersMessage org.gnunet.util.GnunetMessage$Body|150=org.gnunet.dht.MonitorGetRespMessage org.gnunet.util.GnunetMessage$Body|151=org.gnunet.dht.MonitorPutMessage org.gnunet.util.GnunetMessage$Body|171=org.gnunet.statistics.GetResponseEndMessage org.gnunet.util.GnunetMessage$Body|170=org.gnunet.statistics.GetResponseMessage org.gnunet.util.GnunetMessage$Body|169=org.gnunet.statistics.GetMessage org.gnunet.util.GnunetMessage$Body|168=org.gnunet.statistics.SetMessage -org.gnunet.util.GnunetMessage$Body|374=org.gnunet.transport.RequestConnectMessage org.gnunet.util.GnunetMessage$Body|173=org.gnunet.statistics.WatchResponseMessage org.gnunet.util.GnunetMessage$Body|172=org.gnunet.statistics.WatchMessage org.gnunet.util.GnunetMessage$Body|524=org.gnunet.consensus.ConcludeMessage org.gnunet.util.GnunetMessage$Body|521=org.gnunet.consensus.InsertElementMessage org.gnunet.util.GnunetMessage$Body|523=org.gnunet.consensus.NewElementMessage +org.gnunet.util.GnunetMessage$Body|68=org.gnunet.core.DisconnectNotifyMessage +org.gnunet.util.GnunetMessage$Body|70=org.gnunet.core.NotifyInboundTrafficMessage +org.gnunet.util.GnunetMessage$Body|71=org.gnunet.core.NotifyOutboundTrafficMessage +org.gnunet.util.GnunetMessage$Body|64=org.gnunet.core.InitMessage +org.gnunet.util.GnunetMessage$Body|65=org.gnunet.core.InitReplyMessage +org.gnunet.util.GnunetMessage$Body|67=org.gnunet.core.ConnectNotifyMessage +org.gnunet.util.GnunetMessage$Body|76=org.gnunet.core.SendMessage +org.gnunet.util.GnunetMessage$Body|74=org.gnunet.core.SendMessageRequest +org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady +org.gnunet.util.GnunetMessage$Body|460=org.gnunet.testbed.ControllerInitMessage +org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.UpdateMessage +org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.StartMessage +org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage +org.gnunet.util.GnunetMessage$Body|333=org.gnunet.peerinfo.InfoEnd +org.gnunet.util.GnunetMessage$Body|331=org.gnunet.peerinfo.ListAllPeersMessage +org.gnunet.util.GnunetMessage$Body|374=org.gnunet.transport.RequestConnectMessage +org.gnunet.util.GnunetMessage$Body|369=org.gnunet.transport.BlacklistInitMessage +org.gnunet.util.GnunetMessage$Body|371=org.gnunet.transport.BlacklistReplyMessage +org.gnunet.util.GnunetMessage$Body|370=org.gnunet.transport.BlacklistQueryMessage +org.gnunet.util.GnunetMessage$Body|380=org.gnunet.transport.AddressIterateMessage +org.gnunet.util.GnunetMessage$Body|496=org.gnunet.testbed.HelperReplyMessage +org.gnunet.util.GnunetMessage$Body|495=org.gnunet.testbed.HelperInitMessage org.gnunet.util.GnunetMessage$Body|360=org.gnunet.transport.StartMessage org.gnunet.construct.MessageUnion|525=org.gnunet.consensus.ConcludeDoneMessage -# generated 2013/08/22 21:29:40 +# generated 2013/09/04 11:05:50 diff --git a/src/main/resources/org/gnunet/voting/template.espec b/src/main/resources/org/gnunet/voting/template.espec new file mode 100644 index 0000000..b1c9a01 --- /dev/null +++ b/src/main/resources/org/gnunet/voting/template.espec @@ -0,0 +1,36 @@ +[election] + +# human-readable topic description of the election +TOPIC = + +# choices for the voter, separated by a double slash +CHOICES = yes//no + +# starting time of the election, yy/mm/dd hh:mm:ss UTC+x +# authorities affirm that they are available for the election from this point in time +ELECTION_START = + +# deadline for vote submission, yy/mm/dd hh:mm:ss UTC+x +# must be later than ELECTION_START +ELECTION_END = + +# peer identity of the certificate authority for voting eligibility +CA = + +# public key of the election issuer +ISSUER_PUB = + +# the signature of the issuer will be filled in by gnunet-vote-call +# ISSUER_SIGNATURE = + + +[authorities] +# specified as = , one entry for each authority; e.g. +# awesome_authority_one = 123abc + + +[authority-affirmation] +# will be filled in by gnunet-vote-call once +# authorities agreed to participate, with one entry per authority +# = +# where the signature is on the diff --git a/src/test/java/org/gnunet/construct/ConstructTest.java b/src/test/java/org/gnunet/construct/ConstructTest.java index ed6ac51..01754ea 100644 --- a/src/test/java/org/gnunet/construct/ConstructTest.java +++ b/src/test/java/org/gnunet/construct/ConstructTest.java @@ -6,6 +6,8 @@ import org.junit.Test; import java.util.Random; /** + * Miscellaneous tests for org.gnunet.construct. + * * @author Florian Dold */ public class ConstructTest { @@ -17,6 +19,24 @@ public class ConstructTest { public byte[] bytes; } + public static class BoolTestMessage implements Message { + @UInt32 + public boolean x1; + @Int16 + public boolean x2; + } + + @Test + public void test_bool_conversion() { + BoolTestMessage m = new BoolTestMessage(); + m.x1 = true; + m.x2 = true; + byte[] bin = Construct.toBinary(m); + BoolTestMessage m2 = Construct.parseAs(bin, BoolTestMessage.class); + Assert.assertEquals(m.x1, m2.x1); + Assert.assertEquals(m.x2, m2.x2); + } + @Test public void test_ByteFill() { ByteFillTestMessage msg = new ByteFillTestMessage(); diff --git a/src/test/java/org/gnunet/mesh/MeshTest.java b/src/test/java/org/gnunet/mesh/MeshTest.java index ad5eaa3..f8694de 100644 --- a/src/test/java/org/gnunet/mesh/MeshTest.java +++ b/src/test/java/org/gnunet/mesh/MeshTest.java @@ -1,5 +1,7 @@ package org.gnunet.mesh; +import org.gnunet.core.Core; +import org.gnunet.core.PeerIdentityContinuation; import org.gnunet.testing.TestingFixture; import org.gnunet.testing.TestingSubsystem; import org.gnunet.util.*; @@ -16,32 +18,42 @@ public class MeshTest extends TestingFixture { public Mesh m1; public Mesh m2; public void visit(TestMessage m) { + System.out.println("got test message"); m1.destroy(); m2.destroy(); } } - //@Test + @Test (timeout = 5000) public void test_mesh_send() { Program.configureLogging("DEBUG"); - final TestingSubsystem ts = new TestingSubsystem("mesh"); - Configuration cfg = ts.getConfiguration(); - MessageHandler1 mh = new MessageHandler1(); - final Mesh mesh1 = new Mesh(cfg, null, null, null); - final Mesh mesh2 = new Mesh(cfg, new InboundTunnelHandler() { - @Override - public void onInboundTunnel(Mesh.Tunnel tunnel, PeerIdentity initiator) { + // we want the full arm here (starts both mesh and core) + final TestingSubsystem ts = new TestingSubsystem("arm"); + final Configuration cfg = ts.getConfiguration(); - } - }, new TunnelEndHandler() { + final MessageHandler1 mh = new MessageHandler1(); + // FIXME: use CryptoECC instead of Core once available and compatible + Core.withPeerIdentity(cfg, new PeerIdentityContinuation() { @Override - public void onTunnelEnd(Mesh.Tunnel tunnel) { - + public void cont(PeerIdentity peerIdentity) { + System.out.println("got peer identity from core"); + final Mesh mesh1 = new Mesh(cfg, null, null, null); + final Mesh mesh2 = new Mesh(cfg, new InboundTunnelHandler() { + @Override + public void onInboundTunnel(Mesh.Tunnel tunnel, PeerIdentity initiator) { + System.out.println("got inbound tunnel " + initiator); + } + }, new TunnelEndHandler() { + @Override + public void onTunnelEnd(Mesh.Tunnel tunnel) { + System.out.println("tunnel end handler called"); + } + }, mh, 42); + mh.m1 = mesh1; + mh.m2 = mesh2; + Mesh.Tunnel tunnel = mesh1.createTunnel(peerIdentity, 42, false, true, null); + tunnel.send(new TestMessage()); } - }, mh, 42); - mh.m1 = mesh1; - mh.m2 = mesh2; - Mesh.Tunnel tunnel = mesh2.createTunnel(null, 42, false, true, null); - tunnel.send(new TestMessage()); + }); Scheduler.run(); } } diff --git a/src/test/java/org/gnunet/testbed/TestbedTest.java b/src/test/java/org/gnunet/testbed/TestbedTest.java new file mode 100644 index 0000000..4e1af03 --- /dev/null +++ b/src/test/java/org/gnunet/testbed/TestbedTest.java @@ -0,0 +1,41 @@ +package org.gnunet.testbed; + + +import org.gnunet.testing.TestingFixture; +import org.gnunet.util.Configuration; +import org.gnunet.util.Program; +import org.gnunet.util.Scheduler; +import org.gnunet.util.Wrapper; +import org.junit.Assert; +import org.junit.Test; + +public class TestbedTest extends TestingFixture { + + + @Test + public void test_controller_proc() { + final Wrapper success = new Wrapper(false); + new Program() { + + @Override + public void run() { + // use local peer's config, does that really make sense? + Host h = new Host(null, null, getConfiguration(), 0); + final ControllerProc cp = new ControllerProc(); + cp.start("127.0.0.1", h, new ControllerStatusCallback() { + @Override + public void onStartupSuccess(Configuration cfg) { + success.set(true); + cp.stop(); + } + @Override + public void onStartupFailure() { + Assert.fail(); + //To change body of implemented methods use File | Settings | File Templates. + } + }); + } + }.start(); + Assert.assertTrue(success.get()); + } +} diff --git a/src/test/java/org/gnunet/util/CryptoECCTest.java b/src/test/java/org/gnunet/util/CryptoECCTest.java new file mode 100644 index 0000000..cc88409 --- /dev/null +++ b/src/test/java/org/gnunet/util/CryptoECCTest.java @@ -0,0 +1,82 @@ +package org.gnunet.util; + + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Random; + +public class CryptoECCTest { + /** + * Check that signed messages can be verified correctly. + */ + @Test + public void test_sign_success() { + Random r = new Random(); + // the test uses random data, repeat it multiple times! + for (int i = 0; i < 10; i++) { + byte[] msg = new byte[16]; + r.nextBytes(msg); + + CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); + privateKey.d = new byte[32]; + r.nextBytes(privateKey.d); + CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); + + CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); + + boolean valid = CryptoECC.verify(sig, msg, publicKey); + + Assert.assertTrue(valid); + } + } + + /** + * Check that signature verification fails for manipulated data. + */ + @Test + public void test_sign_failure() { + Random r = new Random(); + // the test uses random data, repeat it multiple times! + for (int i = 0; i < 10; i++) { + byte[] msg = new byte[16]; + r.nextBytes(msg); + + CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); + privateKey.d = new byte[32]; + r.nextBytes(privateKey.d); + CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); + + CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); + + msg[0] = (byte) (msg[0] + 1); + + boolean valid = CryptoECC.verify(sig, msg, publicKey); + + Assert.assertFalse(valid); + } + } + + /** + * Check whether ecdh key coincide + */ + @Test + public void test_ecdh() { + Random r = new Random(); + + CryptoECC.PrivateKey privateAlice = new CryptoECC.PrivateKey(); + privateAlice.d = new byte[32]; + r.nextBytes(privateAlice.d); + CryptoECC.PublicKey publicAlice = CryptoECC.computePublicKey(privateAlice); + + CryptoECC.PrivateKey privateBob = new CryptoECC.PrivateKey(); + privateBob.d = new byte[32]; + r.nextBytes(privateBob.d); + CryptoECC.PublicKey publicBob = CryptoECC.computePublicKey(privateBob); + + HashCode ssAlice = CryptoECC.ecdh(privateAlice, publicBob); + HashCode ssBob = CryptoECC.ecdh(privateBob, publicAlice); + + Assert.assertArrayEquals(ssAlice.data, ssBob.data); + } +} -- cgit v1.2.3