Fixed bugs, local communication HMAC added in
authorAli Younis <ayounis@uci.edu>
Tue, 31 Jan 2017 06:05:02 +0000 (22:05 -0800)
committerAli Younis <ayounis@uci.edu>
Tue, 31 Jan 2017 06:05:02 +0000 (22:05 -0800)
version2/src/java/iotcloud/CloudComm.java
version2/src/java/iotcloud/Table.java
version2/src/java/iotcloud/Test.java
version2/src/java/iotcloud/Transaction.java
version2/src/java/iotcloud/TransactionPart.java

index b8c296ba3c0fb3ebeaf8cf482c816414721e3c00..f1f436a1720513a98c59ca58a32fb1f73e644eef 100644 (file)
@@ -17,7 +17,10 @@ import java.security.SecureRandom;
 
 class CloudComm {
        private static final int SALT_SIZE = 8;
-       private static final int TIMEOUT_MILLIS = 100;
+       private static final int TIMEOUT_MILLIS = 25; // 100
+
+       /** Sets the size for the HMAC. */
+       static final int HMAC_SIZE = 32;
 
        private String baseurl;
        private Cipher encryptCipher;
@@ -366,8 +369,18 @@ class CloudComm {
                        return null;
                }
                try {
+
+                       System.out.println("Passing Locally");
+
+                       mac.update(sendData);
+                       byte[] genmac = mac.doFinal();
+                       byte[] totalData = new byte[sendData.length + genmac.length];
+                       System.arraycopy(sendData, 0, totalData, 0, sendData.length);
+                       System.arraycopy(genmac, 0, totalData, sendData.length, genmac.length);
+
                        // Encrypt the data for sending
-                       byte[] encryptedData = encryptCipher.doFinal(sendData);
+                       // byte[] encryptedData = encryptCipher.doFinal(totalData);
+                       byte[] encryptedData = encryptCipher.doFinal(totalData);
 
                        // Open a TCP socket connection to a local device
                        Socket socket = new Socket(host, port);
@@ -385,10 +398,21 @@ class CloudComm {
                        input.readFully(returnData);
                        returnData = decryptCipher.doFinal(returnData);
 
-                       // We are dont with this socket
+                       // We are done with this socket
                        socket.close();
 
-                       return returnData;
+                       mac.update(returnData, 0, returnData.length - HMAC_SIZE);
+                       byte[] realmac = mac.doFinal();
+                       byte[] recmac = new byte[HMAC_SIZE];
+                       System.arraycopy(returnData, returnData.length - realmac.length, recmac, 0, realmac.length);
+
+                       if (!Arrays.equals(recmac, realmac))
+                               throw new Error("Local Error: Invalid HMAC!  Potential Attack!");
+
+                       byte[] returnData2 = new byte[lengthOfReturnData - recmac.length];
+                       System.arraycopy(returnData, 0, returnData2, 0, returnData2.length);
+
+                       return returnData2;
                } catch (SocketTimeoutException e) {
 
                } catch (BadPaddingException e) {
@@ -435,15 +459,33 @@ class CloudComm {
                                // Decrypt the data
                                readData = decryptCipher.doFinal(readData);
 
+                               mac.update(readData, 0, readData.length - HMAC_SIZE);
+                               byte[] genmac = mac.doFinal();
+                               byte[] recmac = new byte[HMAC_SIZE];
+                               System.arraycopy(readData, readData.length - recmac.length, recmac, 0, recmac.length);
+
+                               if (!Arrays.equals(recmac, genmac))
+                                       throw new Error("Local Error: Invalid HMAC!  Potential Attack!");
+
+                               byte[] returnData = new byte[readData.length - recmac.length];
+                               System.arraycopy(readData, 0, returnData, 0, returnData.length);
+
                                // Process the data
-                               byte[] sendData = table.acceptDataFromLocal(readData);
+                               // byte[] sendData = table.acceptDataFromLocal(readData);
+                               byte[] sendData = table.acceptDataFromLocal(returnData);
+
+                               mac.update(sendData);
+                               byte[] realmac = mac.doFinal();
+                               byte[] totalData = new byte[sendData.length + realmac.length];
+                               System.arraycopy(sendData, 0, totalData, 0, sendData.length);
+                               System.arraycopy(realmac, 0, totalData, sendData.length, realmac.length);
 
                                // Encrypt the data for sending
-                               sendData = encryptCipher.doFinal(sendData);
+                               byte[] encryptedData = encryptCipher.doFinal(totalData);
 
                                // Send data to output (length of data, the data)
-                               output.writeInt(sendData.length);
-                               output.write(sendData, 0, sendData.length);
+                               output.writeInt(encryptedData.length);
+                               output.write(encryptedData, 0, encryptedData.length);
                                output.flush();
 
                                // close the socket
index ace90e260466c82209c6da9467957a58572ed2d3..e0d26cdc98d1783fa2b126466d1f82838ea2c469 100644 (file)
@@ -84,9 +84,6 @@ final public class Table {
        private Map<Long, Long> lastArbitrationDataLocalSequenceNumberSeenFromArbitrator = null;
 
 
-
-
-
        public Table(String baseurl, String password, long _localMachineId, int listeningPort) {
                localMachineId = _localMachineId;
                cloud = new CloudComm(this, baseurl, password, listeningPort);
@@ -184,43 +181,18 @@ final public class Table {
                System.out.println("Old:   " + o);
                System.out.println("New:   " + n);
                System.out.println("Size:   " + buffer.size());
+               System.out.println("Commits:   " + liveCommitsTable.size());
+
+               for (Long a : liveCommitsTable.keySet()) {
+                       for (Long b : liveCommitsTable.get(a).keySet()) {
+                               for (KeyValue kv : liveCommitsTable.get(a).get(b).getKeyValueUpdateSet()) {
+                                       System.out.print(kv + " ");
+                               }
+                               System.out.print("|| ");
+                       }
+                       System.out.println();
+               }
 
-               // List<IoTString> strList = new ArrayList<IoTString>();
-               // for (int i = 0; i < 100; i++) {
-               //      String keyA = "a" + i;
-               //      String keyB = "b" + i;
-               //      String keyC = "c" + i;
-               //      String keyD = "d" + i;
-
-               //      IoTString iKeyA = new IoTString(keyA);
-               //      IoTString iKeyB = new IoTString(keyB);
-               //      IoTString iKeyC = new IoTString(keyC);
-               //      IoTString iKeyD = new IoTString(keyD);
-
-               //      strList.add(iKeyA);
-               //      strList.add(iKeyB);
-               //      strList.add(iKeyC);
-               //      strList.add(iKeyD);
-               // }
-
-
-               // for (Long l : commitMap.keySet()) {
-               //      for (Long l2 : commitMap.get(l).keySet()) {
-               //              for (KeyValue kv : commitMap.get(l).get(l2).getkeyValueUpdateSet()) {
-               //                      strList.remove(kv.getKey());
-               //                      System.out.print(kv.getKey() + "    ");
-               //              }
-               //      }
-               // }
-
-               // System.out.println();
-               // System.out.println();
-
-               // for (IoTString s : strList) {
-               //      System.out.print(s + "    ");
-               // }
-               // System.out.println();
-               // System.out.println(strList.size());
        }
 
        /**
@@ -559,11 +531,8 @@ final public class Table {
                                        }
 
                                        for (Transaction transaction : transactionPartsSent.keySet()) {
-
-
                                                transaction.resetServerFailure();
 
-
                                                // Update which transactions parts still need to be sent
                                                transaction.removeSentParts(transactionPartsSent.get(transaction));
 
@@ -603,8 +572,7 @@ final public class Table {
                        }
                } catch (ServerException e) {
 
-                       System.out.println("Server Failure:   " + e.getType());
-
+                       // System.out.println("Server Failure:   " + e.getType());
 
                        if (e.getType() != ServerException.TypeInputTimeout) {
                                // e.printStackTrace();
@@ -720,6 +688,7 @@ final public class Table {
                        part.encode(bbEncode);
                }
 
+
                // Send by local
                byte[] returnData = cloud.sendLocalData(sendData, localCommunicationInformation.getFirst(), localCommunicationInformation.getSecond());
 
@@ -773,6 +742,7 @@ final public class Table {
        }
 
        public synchronized byte[] acceptDataFromLocal(byte[] data) {
+
                // Decode the data
                ByteBuffer bbDecode = ByteBuffer.wrap(data);
                long lastArbitratedSequenceNumberSeen = bbDecode.getLong();
@@ -1557,7 +1527,6 @@ final public class Table {
                                        status.setStatus(TransactionStatus.StatusAborted);
                                }
                        } else {
-
                                Set addAbortSet = new HashSet<Abort>();
 
 
@@ -1829,8 +1798,6 @@ final public class Table {
                                        lastCommitSeenSequenceNumberByArbitratorTable.put(commit.getMachineId(), commit.getSequenceNumber());
                                }
 
-
-
                                // Update the last transaction that was updated if we can
                                if (commit.getTransactionSequenceNumber() != -1) {
                                        Long lastTransactionNumber = lastArbitratedTransactionNumberByArbitratorTable.get(commit.getMachineId());
@@ -1844,8 +1811,6 @@ final public class Table {
                                // We processed a new commit that we havent seen before
                                didProcessANewCommit = true;
 
-
-
                                // Update the committed table of keys and which commit is using which key
                                for (KeyValue kv : commit.getKeyValueUpdateSet()) {
                                        committedKeyValueTable.put(kv.getKey(), kv);
index 1a627a9561698164af5109e61fff819523ab43fe..d6598628b86c7ce7551d97a6e7bc540d77b566a1 100644 (file)
@@ -773,6 +773,7 @@ public class Test {
         while (t1.update() == false) {}
         while (t2.update() == false) {}
         while (t1.update() == false) {}
+        while (t2.update() == false) {}
 
         System.out.println("Checking Key-Values...");
         for (int i = 0; i < NUMBER_OF_TESTS; i++) {
index f444ded5f8c294106e18914af138c6461f777250..8494625a2907546414115568fea6240df9e7c146 100644 (file)
@@ -14,6 +14,7 @@ class Transaction {
     private Set<Integer> missingParts = null;
     private List<Integer> partsPendingSend = null;
     private boolean isComplete = false;
+    private boolean hasLastPart = false;
     private Set<KeyValue> keyValueGuardSet = null;
     private Set<KeyValue> keyValueUpdateSet = null;
     private boolean isDead = false;
@@ -73,6 +74,7 @@ class Transaction {
             previoslySeenPart.setDead();
         } else if (newPart.isLastPart()) {
             missingParts = new HashSet<Integer>();
+            hasLastPart = true;
 
             for (int i = 0; i < newPart.getPartNumber(); i++) {
                 if (parts.get(i) == null) {
@@ -81,7 +83,7 @@ class Transaction {
             }
         }
 
-        if (!isComplete) {
+        if (!isComplete && hasLastPart) {
 
             // We have seen this part so remove it from the set of missing parts
             missingParts.remove(newPart.getPartNumber());
@@ -297,7 +299,6 @@ class Transaction {
                 }
             } else {
                 if (kv != null) {
-                    System.out.println("kvGuard was nulled:  " + kv);
                     return false;
                 }
             }
index 17d8e4481be95da2f62ea991b81f83a406197777..7739eefe926d4727fb13803fc76c72c8ccabc4e2 100644 (file)
@@ -96,8 +96,7 @@ class TransactionPart extends Entry {
         long clientLocalSequenceNumber = bb.getLong();
         int partNumber = bb.getInt();
         int dataSize = bb.getInt();
-        Boolean isLastPart = bb.get() == 1;
-
+        Boolean isLastPart = (bb.get() == 1);
         // Get the data
         byte[] data = new byte[dataSize];
         bb.get(data);