summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/Packet.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/noreply/fancydress/type3/Packet.java')
-rw-r--r--src/org/noreply/fancydress/type3/Packet.java78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/org/noreply/fancydress/type3/Packet.java b/src/org/noreply/fancydress/type3/Packet.java
new file mode 100644
index 0000000..3d76cbe
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/Packet.java
@@ -0,0 +1,78 @@
+package org.noreply.fancydress.type3;
+
+import org.noreply.fancydress.misc.Util;
+import org.noreply.fancydress.type3.routing.*;
+import org.noreply.fancydress.crypto.*;
+import org.noreply.fancydress.status.*;
+import java.util.*;
+
+public class Packet {
+
+ private byte[] packet;
+ private Routing thisRoute;
+
+ public Packet(
+ Path path,
+ RoutingDestination address,
+ Payload payload)
+ throws Mix3BadArgumentsChainTooLongException
+ {
+ ForwardLeg leg2 = new ForwardLeg(path.getSecondHalf(), address);
+ if (!(leg2.getRoute() instanceof RoutingForward))
+ throw new Error("Routing Type of second leg is not a forward type.");
+ ForwardLeg leg1 = new ForwardLeg(path.getFirstHalf(), ((RoutingForward)leg2.getRoute()).asSwap());
+ makePacket(leg1, leg2, payload);
+ }
+
+ public Packet(
+ HalfPath path,
+ SURB surb,
+ Payload payload)
+ throws Mix3BadArgumentsChainTooLongException
+ {
+ ForwardLeg leg1 = new ForwardLeg(path, surb.getRoute());
+ makePacket(leg1, surb, payload);
+ }
+
+ public static boolean isPacketVersionSupported(String s) {
+ return s.equals(SingleLeg.MAJOR_VERSION + "." + SingleLeg.MINOR_VERSION);
+ }
+
+ private void makePacket(ForwardLeg leg1, SingleLeg leg2, Payload payload) {
+ byte p[] = payload.asOctets();
+ byte h1[] = leg1.asOctets();
+ byte h2[] = leg2.asOctets();
+
+ // Phase 1
+ if (leg2 instanceof SURB) {
+ byte[] k = ((SURB) leg2).getEncryptionKey();
+ p = CryptoPrimitives.sprpDecrypt(k, "PAYLOAD ENCRYPT", p);
+ } else {
+ byte[][] sk = ((ForwardLeg) leg2).getSharedKeys();
+ for (int i=sk.length-1; i>=0; i--)
+ p = CryptoPrimitives.sprpEncrypt(sk[i], "PAYLOAD ENCRYPT", p);
+ }
+
+ // Phase 2
+ h2 = CryptoPrimitives.sprpEncrypt(CryptoPrimitives.hash(p), "HIDE HEADER", h2);
+ p = CryptoPrimitives.sprpEncrypt(CryptoPrimitives.hash(h2), "HIDE PAYLOAD", p);
+
+ byte[][] sk = leg1.getSharedKeys();
+ for (int i=sk.length-1; i>=0; i--) {
+ h2 = CryptoPrimitives.sprpEncrypt(sk[i], "HEADER ENCRYPT", h2);
+ p = CryptoPrimitives.sprpEncrypt(sk[i], "PAYLOAD ENCRYPT", p);
+ }
+
+ packet = Util.concat(Util.concat(h1,h2),p);
+ thisRoute = leg1.getRoute();
+ }
+
+ public Routing getRoute() {
+ return thisRoute;
+ }
+
+ public byte[] asOctets() {
+ return packet;
+ }
+}
+