summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/Payload.java
blob: 73027cd8f26ce178fbcf22efe30feaabe9e875ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* $Id$ */
package org.noreply.fancydress.type3;

import java.io.*;
import java.util.zip.*;
import org.noreply.fancydress.crypto.*;
import org.noreply.fancydress.misc.Util;
import org.noreply.fancydress.type3.routing.*;

public class Payload {
	byte[][] payloads;
	RoutingDestination[] route;

	public Payload(RoutingDestination route, String body) {
		try {
			PipedOutputStream poMessage = new PipedOutputStream();
			PipedInputStream piMessage = new PipedInputStream( poMessage );

			Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION);
			DeflaterOutputStream compresserStream = new DeflaterOutputStream(poMessage, compresser);

			/* FIXME, do a more clever and robust way of reading/writing */

			byte[] message = Util.toOctets(body);
			compresserStream.write(message, 0, message.length);
			compresserStream.close();

			byte[] compressed = new byte[message.length]; // UGH
			int read = piMessage.read(compressed,0,compressed.length);
			compressed = Util.slice(compressed, 0, read);

			byte[] padding = CryptoPrimitives.rand( 28*1024 - compressed.length - 22);

			byte[] payload = new byte[28*1024];
			int pos = 0;

			int firstWord = compressed.length;

			payload[pos] = (byte) ( (firstWord >> 8) & 0xff);
			pos++;
			payload[pos] = (byte) (  firstWord       & 0xff);
			pos++;

			System.arraycopy(CryptoPrimitives.hash(compressed, padding), 0, payload, pos, CryptoPrimitives.HASH_LEN);
			pos += CryptoPrimitives.HASH_LEN;

			System.arraycopy(compressed, 0, payload, pos, compressed.length);
			pos += compressed.length;

			System.arraycopy(padding, 0, payload,  pos, padding.length);
			pos += padding.length;

			if (pos != 28*1024)
				throw new Error("did not fill in 28k bytes");

			payloads = new byte[1][];
			payloads[0] = payload;
		} catch (Exception e) {
			throw new Error(e);
		};
		this.route = new RoutingDestination[1];
		this.route[0] = route;

		// Return a singleton payload containing:
		//  Flag 0 | Int(15,LEN(M_C)) | Hash(M_C | PADDING) | M_C | PADDING

	}

	public int numPackets() {
		return payloads.length;
	}

	public byte[] getPayload(int i) {
		return payloads[i];
	}

	public RoutingDestination getRoute(int i) {
		return route[i];
	}
}