2 import java.util.Vector;
3 import java.nio.ByteBuffer;
4 import javax.crypto.Mac;
5 import java.util.Arrays;
8 public static final int SLOT_SIZE=2048;
9 public static final int HMAC_SIZE=32;
12 private byte[] prevhmac;
14 private long machineid;
15 private Vector<Entry> entries;
17 Slot(long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac, Vector<Entry> _entries) {
25 Slot(long _seqnum, byte[] _bytes) {
33 byte[] getPrevHMAC() {
37 Vector<Entry> getEntries() {
41 static Slot decode(byte[] array, Mac mac) {
42 mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
43 byte[] realmac=mac.doFinal();
45 ByteBuffer bb=ByteBuffer.wrap(array);
46 byte[] hmac=new byte[HMAC_SIZE];
47 byte[] prevhmac=new byte[HMAC_SIZE];
50 if (!Arrays.equals(realmac, hmac))
51 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
53 long seqnum=bb.getLong();
54 long machineid=bb.getLong();
55 int numentries=bb.getInt();
56 Vector<Entry> entries=new Vector<Entry>();
57 for(int i=0;i<numentries;i++) {
58 entries.add(Entry.decode(bb));
61 return new Slot(seqnum, machineid, prevhmac, hmac, entries);
64 byte[] encode(Mac mac) {
65 byte[] array=new byte[SLOT_SIZE];
66 ByteBuffer bb=ByteBuffer.wrap(array);
67 bb.position(HMAC_SIZE); //Leave space for the HMACs
70 bb.putLong(machineid);
71 bb.putInt(entries.size());
72 for(Entry entry:entries) {
76 mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
77 byte[] realmac=mac.doFinal();
83 long getSequenceNumber() {
91 public String toString() {
92 return "<"+getSequenceNumber()+", "+new String(getBytes())+">";