public static final int SLOT_SIZE=2048;
public static final int HMAC_SIZE=32;
- long seqnum;
- byte[] prevhmac;
- byte[] hmac;
- long machineid;
- Vector<Entry> entries;
+ private long seqnum;
+ private byte[] prevhmac;
+ private byte[] hmac;
+ private long machineid;
+ private Vector<Entry> entries;
Slot(long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac, Vector<Entry> _entries) {
seqnum=_seqnum;
byte[] getPrevHMAC() {
return prevhmac;
}
+
+ Vector<Entry> getEntries() {
+ return entries;
+ }
static Slot decode(byte[] array, Mac mac) {
mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
bb.get(hmac);
bb.get(prevhmac);
if (!Arrays.equals(realmac, hmac))
- throw new Error("Invalid HMAC! Potential Attack!");
+ throw new Error("Server Error: Invalid HMAC! Potential Attack!");
long seqnum=bb.getLong();
long machineid=bb.getLong();
public class Table {
int numslots;
HashMap<IoTString, IoTString> table=new HashMap<IoTString, IoTString>();
+ HashMap<Long, Long> lastmessage=new HashMap<Long, Long>();
SlotBuffer buffer;
CloudComm cloud;
private Mac hmac;
long sequencenumber;
+ long machineid;
- public Table(String baseurl, String password) {
- initCloud(baseurl, password);
+ public Table(String baseurl, String password, long _machineid) {
+ machineid=_machineid;
buffer = new SlotBuffer();
sequencenumber = 1;
+ initCloud(baseurl, password);
}
private void initCloud(String baseurl, String password) {
void validateandupdate(Slot[] newslots) {
//The cloud communication layer has checked slot HMACs already
//before decoding
-
if (newslots.length==0)
return;
long firstseqnum=newslots[0].getSequenceNumber();
if (firstseqnum < sequencenumber)
- throw new Error("Server sent older slots!");
+ throw new Error("Server Error: Sent older slots!");
- checkHMACChain(newslots);
-
- if (firstseqnum == (buffer.getNewestSeqNum()+1)) {
- //contiguous update
- } else {
- //non-contiguous update
+ SlotIndexer indexer = new SlotIndexer(newslots, buffer);
+ checkHMACChain(indexer, newslots);
+ for(Slot slot: newslots) {
+ processSlot(indexer, slot);
}
-
}
- void checkHMACChain(Slot[] newslots) {
- if (newslots[0].getSequenceNumber() == (buffer.getNewestSeqNum()+1)) {
- Slot prevslot=buffer.getSlot(buffer.getNewestSeqNum());
- Slot currslot=newslots[0];
- if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
- throw new Error("Error in HMAC Chain");
- }
+ void processEntry(KeyValue entry, SlotIndexer indexer, Slot slot) {
- for(int i=1; i < newslots.length; i++) {
- Slot prevslot=newslots[i-1];
- Slot currslot=newslots[i];
- if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
- throw new Error("Error in HMAC Chain");
+ }
+
+ void processEntry(LastMessage entry, SlotIndexer indexer, Slot slot) {
+
+ }
+
+ void processEntry(RejectedMessage entry, SlotIndexer indexer, Slot slot) {
+
+ }
+
+ void processEntry(TableStatus entry, SlotIndexer indexer, Slot slot) {
+
+ }
+
+ void processSlot(SlotIndexer indexer, Slot slot) {
+ for(Entry entry : slot.getEntries()) {
+ switch(entry.getType()) {
+ case Entry.TypeKeyValue:
+ processEntry((KeyValue)entry, indexer, slot);
+ break;
+ case Entry.TypeLastMessage:
+ processEntry((LastMessage)entry, indexer, slot);
+ break;
+ case Entry.TypeRejectedMessage:
+ processEntry((RejectedMessage)entry, indexer, slot);
+ break;
+ case Entry.TypeTableStatus:
+ processEntry((TableStatus)entry, indexer, slot);
+ break;
+ default:
+ throw new Error("Unrecognized type: "+entry.getType());
+ }
}
}
+ void checkHMACChain(SlotIndexer indexer, Slot[] newslots) {
+ for(int i=0; i < newslots.length; i++) {
+ Slot currslot=newslots[i];
+ Slot prevslot=indexer.getSlot(currslot.getSequenceNumber()-1);
+ if (prevslot != null &&
+ !Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
+ throw new Error("Server Error: Invalid HMAC Chain");
+ }
+ }
}