Timing, Attacks
[iotcloud.git] / version2 / src / java / iotcloud / CloudComm.java
index f1f436a1720513a98c59ca58a32fb1f73e644eef..5e60e3c4b90f1cd82f6d88a501b662af1f95b8d2 100644 (file)
@@ -17,7 +17,7 @@ import java.security.SecureRandom;
 
 class CloudComm {
        private static final int SALT_SIZE = 8;
-       private static final int TIMEOUT_MILLIS = 25; // 100
+       private static final int TIMEOUT_MILLIS = 2000; // 100
 
        /** Sets the size for the HMAC. */
        static final int HMAC_SIZE = 32;
@@ -34,16 +34,20 @@ class CloudComm {
        private Thread localServerThread = null;
        private boolean doEnd = false;
 
+       private TimingSingleton timer = null;
+
        /**
         * Empty Constructor needed for child class.
         */
        CloudComm() {
+               timer = TimingSingleton.getInstance();
        }
 
        /**
         * Constructor for actual use. Takes in the url and password.
         */
        CloudComm(Table _table,  String _baseurl, String _password, int _listeningPort) {
+               timer = TimingSingleton.getInstance();
                this.table = _table;
                this.baseurl = _baseurl;
                this.password = _password;
@@ -137,6 +141,8 @@ class CloudComm {
                        random.nextBytes(saltTmp);
 
                        URL url = new URL(baseurl + "?req=setsalt");
+                       
+                       timer.startTime();
                        URLConnection con = url.openConnection();
                        HttpURLConnection http = (HttpURLConnection) con;
 
@@ -144,12 +150,14 @@ class CloudComm {
                        http.setFixedLengthStreamingMode(saltTmp.length);
                        http.setDoOutput(true);
                        http.setConnectTimeout(TIMEOUT_MILLIS);
+
+                       
                        http.connect();
 
                        OutputStream os = http.getOutputStream();
                        os.write(saltTmp);
                        os.flush();
-
+                       
                        int responsecode = http.getResponseCode();
                        if (responsecode != HttpURLConnection.HTTP_OK) {
                                // TODO: Remove this print
@@ -157,9 +165,12 @@ class CloudComm {
                                throw new Error("Invalid response");
                        }
 
+                       timer.endTime();
+
                        salt = saltTmp;
                } catch (Exception e) {
                        // e.printStackTrace();
+                       timer.endTime();
                        throw new ServerException("Failed setting salt", ServerException.TypeConnectTimeout);
                }
        }
@@ -177,13 +188,18 @@ class CloudComm {
                }
                try {
 
+                       timer.startTime();
                        con = url.openConnection();
                        http = (HttpURLConnection) con;
                        http.setRequestMethod("POST");
                        http.setConnectTimeout(TIMEOUT_MILLIS);
                        http.setReadTimeout(TIMEOUT_MILLIS);
+
+                       
                        http.connect();
+                       timer.endTime();
                } catch (SocketTimeoutException e) {
+                       timer.endTime();
                        throw new ServerException("getSalt failed", ServerException.TypeConnectTimeout);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -192,6 +208,8 @@ class CloudComm {
 
                try {
 
+                       timer.startTime();
+
                        int responsecode = http.getResponseCode();
                        if (responsecode != HttpURLConnection.HTTP_OK) {
                                // TODO: Remove this print
@@ -206,11 +224,17 @@ class CloudComm {
                                byte [] tmp = new byte[salt_length];
                                dis.readFully(tmp);
                                salt = tmp;
+                               timer.endTime();
+
                                return true;
                        } else {
+                               timer.endTime();
+
                                return false;
                        }
                } catch (SocketTimeoutException e) {
+                       timer.endTime();
+
                        throw new ServerException("getSalt failed", ServerException.TypeInputTimeout);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -240,7 +264,12 @@ class CloudComm {
                        byte[] bytes = slot.encode(mac);
                        bytes = encryptCipher.doFinal(bytes);
 
+
+
+
                        url = buildRequest(true, sequencenumber, max);
+
+                       timer.startTime();
                        con = url.openConnection();
                        http = (HttpURLConnection) con;
 
@@ -255,10 +284,17 @@ class CloudComm {
                        os.write(bytes);
                        os.flush();
 
+                       timer.endTime();
+
+
                        // System.out.println("Bytes Sent: " + bytes.length);
                } catch (ServerException e) {
+                       timer.endTime();
+
                        throw e;
                } catch (SocketTimeoutException e) {
+                       timer.endTime();
+
                        throw new ServerException("putSlot failed", ServerException.TypeConnectTimeout);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -268,19 +304,26 @@ class CloudComm {
 
 
                try {
+                       timer.startTime();
                        InputStream is = http.getInputStream();
                        DataInputStream dis = new DataInputStream(is);
                        byte[] resptype = new byte[7];
                        dis.readFully(resptype);
+                       timer.endTime();
 
                        if (Arrays.equals(resptype, "getslot".getBytes()))
+                       {       
                                return processSlots(dis);
+                       }
                        else if (Arrays.equals(resptype, "putslot".getBytes()))
+                       {
                                return null;
+                       }
                        else
                                throw new Error("Bad response to putslot");
 
                } catch (SocketTimeoutException e) {
+                               timer.endTime();
                        throw new ServerException("putSlot failed", ServerException.TypeInputTimeout);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -306,15 +349,25 @@ class CloudComm {
                        }
 
                        url = buildRequest(false, sequencenumber, 0);
+                       timer.startTime();
                        con = url.openConnection();
                        http = (HttpURLConnection) con;
                        http.setRequestMethod("POST");
                        http.setConnectTimeout(TIMEOUT_MILLIS);
                        http.setReadTimeout(TIMEOUT_MILLIS);
+
+                       
+
                        http.connect();
+                       timer.endTime();
+
                } catch (SocketTimeoutException e) {
+                       timer.endTime();
+
                        throw new ServerException("getSlots failed", ServerException.TypeConnectTimeout);
                } catch (ServerException e) {
+                       timer.endTime();
+
                        throw e;
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -322,15 +375,22 @@ class CloudComm {
                }
 
                try {
-                       InputStream is = http.getInputStream();
+                       
+                       timer.startTime();
+                       InputStream is = http.getInputStream(); 
                        DataInputStream dis = new DataInputStream(is);
                        byte[] resptype = new byte[7];
+                       
                        dis.readFully(resptype);
+                       timer.endTime();
+
                        if (!Arrays.equals(resptype, "getslot".getBytes()))
                                throw new Error("Bad Response: " + new String(resptype));
-                       else
-                               return processSlots(dis);
+
+                       return processSlots(dis);
                } catch (SocketTimeoutException e) {
+                       timer.endTime();
+
                        throw new ServerException("getSlots failed", ServerException.TypeInputTimeout);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -388,6 +448,8 @@ class CloudComm {
                        DataOutputStream output = new DataOutputStream(socket.getOutputStream());
                        DataInputStream input = new DataInputStream(socket.getInputStream());
 
+
+                       timer.startTime();
                        // Send data to output (length of data, the data)
                        output.writeInt(encryptedData.length);
                        output.write(encryptedData, 0, encryptedData.length);
@@ -396,6 +458,9 @@ class CloudComm {
                        int lengthOfReturnData = input.readInt();
                        byte[] returnData = new byte[lengthOfReturnData];
                        input.readFully(returnData);
+
+                       timer.endTime();
+
                        returnData = decryptCipher.doFinal(returnData);
 
                        // We are done with this socket
@@ -456,6 +521,8 @@ class CloudComm {
                                byte[] readData = new byte[dataSize];
                                input.readFully(readData);
 
+                               timer.endTime();
+
                                // Decrypt the data
                                readData = decryptCipher.doFinal(readData);
 
@@ -483,6 +550,8 @@ class CloudComm {
                                // Encrypt the data for sending
                                byte[] encryptedData = encryptCipher.doFinal(totalData);
 
+
+                               timer.startTime();
                                // Send data to output (length of data, the data)
                                output.writeInt(encryptedData.length);
                                output.write(encryptedData, 0, encryptedData.length);