summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/SURB.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/noreply/fancydress/type3/SURB.java')
-rw-r--r--src/org/noreply/fancydress/type3/SURB.java84
1 files changed, 76 insertions, 8 deletions
diff --git a/src/org/noreply/fancydress/type3/SURB.java b/src/org/noreply/fancydress/type3/SURB.java
index 400db34..4ef8948 100644
--- a/src/org/noreply/fancydress/type3/SURB.java
+++ b/src/org/noreply/fancydress/type3/SURB.java
@@ -4,23 +4,91 @@ package org.noreply.fancydress.type3;
import org.noreply.fancydress.type3.routing.*;
import org.noreply.fancydress.status.*;
import org.noreply.fancydress.crypto.*;
+import org.noreply.fancydress.misc.*;
public class SURB extends SingleLeg {
+ public static final byte[] VERSION = {0, 1};
+ public static final String ARMOR_VERSION = "0.2";
+ private byte[] sharedSecret;
- public SURB (Path path, RoutingDestination address) throws Mix3BadArgumentsChainTooLongException {
+ public SURB (HalfPath path, byte[] secret, RoutingDestination address) throws Mix3BadArgumentsChainTooLongException {
super();
+ byte[] seed;
+ byte[] validateHash;
+ byte[] validate = Util.toOctets("Validate");
- byte[][] sharedKeys = {};
- Hop[] hops = new Hop[0]; // path.getHops();
+ Hop[] hops = path.getHops();
- /* FIXME */
+ do {
+ seed = CryptoPrimitives.rand(20);
+ seed[0] &= 0x7f;
+ validateHash = CryptoPrimitives.hash(seed, secret, validate);
+ } while (validateHash[validateHash.length-1] == 0);
- makeLeg ( hops, sharedKeys, address);
+ byte[] key = Util.slice(CryptoPrimitives.hash(seed, secret, Util.toOctets("Generate")), 0,CryptoPrimitives.KEY_LEN);
+ byte[] stream = CryptoPrimitives.prng(key, CryptoPrimitives.KEY_LEN*(hops.length + 1));
+ sharedSecret = Util.slice(stream, CryptoPrimitives.KEY_LEN*hops.length, CryptoPrimitives.KEY_LEN);
+ byte[][] sharedKeys = new byte[hops.length][];
+ for (int i=0; i<hops.length; i++)
+ sharedKeys[i] = Util.slice(stream, (hops.length-i-1)*CryptoPrimitives.KEY_LEN, CryptoPrimitives.KEY_LEN);
+
+ makeLeg(hops, sharedKeys, address);
};
- public byte[] getEncryptionKey() {
- return new byte[16];
+ /*
+ Begin Marker: 4 octets
+ Version: 2 octets
+ Use-by-Date: 4 octets
+ SURB header: 2048 octets
+ Routing Size: 2 octets
+ Routing Type: 2 octets
+ Encryption key: 16 octets
+ Routing Info: (Routing Size) octets
+ */
+
+ public String export() {
+ byte[] beginMarker = Util.toOctets("SURB");
+ int useBy = 1068595200; //FIXME // Y2k36
+ byte[] routingInformation = getRoute().getRoutingInformation();
+ int routingSize = routingInformation.length;
+ int routingType = getRoute().getRoutingType();
+
+ byte[] result = new byte[4+2+4+SINGLE_HEADER_LEN+2+2+CryptoPrimitives.KEY_LEN+routingSize];
+
+ int pos = 0;
+ System.arraycopy(beginMarker, 0, result, pos, beginMarker.length);
+ pos += beginMarker.length;
+ System.arraycopy(VERSION, 0, result, pos, VERSION.length);
+ pos += VERSION.length;
+ result[pos] = (byte) ( (useBy >>24) & 0xff);
+ pos++;
+ result[pos] = (byte) ( (useBy >>16) & 0xff);
+ pos++;
+ result[pos] = (byte) ( (useBy >> 8) & 0xff);
+ pos++;
+ result[pos] = (byte) ( (useBy ) & 0xff);
+ pos++;
+ System.arraycopy(super.asOctets(), 0, result, pos, SINGLE_HEADER_LEN);
+ pos += SINGLE_HEADER_LEN;
+ result[pos] = (byte) ( (routingSize >> 8) & 0xff);
+ pos++;
+ result[pos] = (byte) ( routingSize & 0xff);
+ pos++;
+ result[pos] = (byte) ( (routingType >> 8) & 0xff);
+ pos++;
+ result[pos] = (byte) ( routingType & 0xff);
+ pos++;
+ System.arraycopy(sharedSecret, 0, result, pos, CryptoPrimitives.KEY_LEN);
+ pos += CryptoPrimitives.KEY_LEN;
+ System.arraycopy(routingInformation, 0, result, pos, routingSize);
+ pos += routingSize;
+
+ if (pos != result.length)
+ throw new Error("did not fill in expected number of bytes");
+
+ String[] headers = new String[1];
+ headers[0] = "Version: "+ARMOR_VERSION;
+ return Util.armor(result, "TYPE III REPLY BLOCK", headers);
}
}
-