From: Ali Younis Date: Tue, 31 Jan 2017 06:05:02 +0000 (-0800) Subject: Fixed bugs, local communication HMAC added in X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ed49d9558c43cec9fda16bdc8792f041d5394e79;p=iotcloud.git Fixed bugs, local communication HMAC added in --- diff --git a/version2/src/java/iotcloud/CloudComm.java b/version2/src/java/iotcloud/CloudComm.java index b8c296b..f1f436a 100644 --- a/version2/src/java/iotcloud/CloudComm.java +++ b/version2/src/java/iotcloud/CloudComm.java @@ -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 diff --git a/version2/src/java/iotcloud/Table.java b/version2/src/java/iotcloud/Table.java index ace90e2..e0d26cd 100644 --- a/version2/src/java/iotcloud/Table.java +++ b/version2/src/java/iotcloud/Table.java @@ -84,9 +84,6 @@ final public class Table { private Map 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 strList = new ArrayList(); - // 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(); @@ -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); diff --git a/version2/src/java/iotcloud/Test.java b/version2/src/java/iotcloud/Test.java index 1a627a9..d659862 100644 --- a/version2/src/java/iotcloud/Test.java +++ b/version2/src/java/iotcloud/Test.java @@ -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++) { diff --git a/version2/src/java/iotcloud/Transaction.java b/version2/src/java/iotcloud/Transaction.java index f444ded..8494625 100644 --- a/version2/src/java/iotcloud/Transaction.java +++ b/version2/src/java/iotcloud/Transaction.java @@ -14,6 +14,7 @@ class Transaction { private Set missingParts = null; private List partsPendingSend = null; private boolean isComplete = false; + private boolean hasLastPart = false; private Set keyValueGuardSet = null; private Set keyValueUpdateSet = null; private boolean isDead = false; @@ -73,6 +74,7 @@ class Transaction { previoslySeenPart.setDead(); } else if (newPart.isLastPart()) { missingParts = new HashSet(); + 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; } } diff --git a/version2/src/java/iotcloud/TransactionPart.java b/version2/src/java/iotcloud/TransactionPart.java index 17d8e44..7739eef 100644 --- a/version2/src/java/iotcloud/TransactionPart.java +++ b/version2/src/java/iotcloud/TransactionPart.java @@ -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);