More Java Code
[iotcloud.git] / src / java / iotcloud / Table.java
1 package iotcloud;
2 import java.util.HashMap;
3 import java.util.Arrays;
4 import javax.crypto.spec.*;
5 import javax.crypto.*;
6
7 public class Table {
8         int numslots;
9         HashMap<IoTString, IoTString> table=new HashMap<IoTString, IoTString>();
10         SlotBuffer buffer;
11         CloudComm cloud;
12         private Mac hmac;
13         long sequencenumber;
14         
15         public Table(String baseurl, String password) {
16                 initCloud(baseurl, password);
17                 buffer = new SlotBuffer();
18                 sequencenumber = 1;
19         }
20
21         private void initCloud(String baseurl, String password) {
22                 try {
23                         SecretKeySpec secret=getKey(password);
24                         Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
25                         encryptCipher.init(Cipher.ENCRYPT_MODE, secret);
26                         Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
27                         decryptCipher.init(Cipher.DECRYPT_MODE, secret);
28                         hmac = Mac.getInstance("HmacSHA256");
29                         hmac.init(secret);
30                         cloud=new CloudComm(baseurl, encryptCipher, decryptCipher, hmac);
31                 } catch (Exception e) {
32                         throw new Error("Failed To Initialize Ciphers");
33                 }
34         }
35
36         private SecretKeySpec getKey(String password) {
37                 try {
38                         PBEKeySpec keyspec = new PBEKeySpec(password.toCharArray());
39                         SecretKey key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(keyspec);
40                         SecretKeySpec secret = new SecretKeySpec(key.getEncoded(), "AES");
41                         return secret;
42                 } catch (Exception e) {
43                         throw new Error("Failed generating key.");
44                 }
45         }
46
47         public void update() {
48                 Slot[] newslots=cloud.getSlots(sequencenumber);
49                 validateandupdate(newslots);
50         }
51
52         void validateandupdate(Slot[] newslots) {
53                 //The cloud communication layer has checked slot HMACs already
54                 //before decoding
55
56                 if (newslots.length==0)
57                         return;
58
59                 long firstseqnum=newslots[0].getSequenceNumber();
60                 if (firstseqnum < sequencenumber)
61                         throw new Error("Server sent older slots!");
62
63                 checkHMACChain(newslots);
64                 
65                 if (firstseqnum == (buffer.getNewestSeqNum()+1)) {
66                         //contiguous update
67                 } else {
68                         //non-contiguous update
69                 }
70
71                 
72         }
73
74         void checkHMACChain(Slot[] newslots) {
75                 if (newslots[0].getSequenceNumber() == (buffer.getNewestSeqNum()+1)) {
76                         Slot prevslot=buffer.getSlot(buffer.getNewestSeqNum());
77                         Slot currslot=newslots[0];
78                         if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
79                                 throw new Error("Error in HMAC Chain");
80                 }
81
82                 for(int i=1; i < newslots.length; i++) {
83                         Slot prevslot=newslots[i-1];
84                         Slot currslot=newslots[i];
85                         if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
86                                 throw new Error("Error in HMAC Chain");
87                 }
88         }
89         
90 }