From 19547c373c92a2221d680840999e88d0884549b4 Mon Sep 17 00:00:00 2001 From: joelbandi Date: Tue, 26 Jul 2016 05:56:21 -0700 Subject: [PATCH 01/16] Added Js code (40%) --- .gitignore | 5 +++ src/java/iotcloud/Slot.java | 2 +- src/js/iotjs/.babelrc | 1 + src/js/iotjs/.bowerrc | 3 ++ src/js/iotjs/.editorconfig | 13 ++++++ src/js/iotjs/.jshintrc | 20 +++++++++ src/js/iotjs/README.md | 21 ++++++++++ src/js/iotjs/bower.json | 6 +++ src/js/iotjs/examples/index.html | 11 +++++ src/js/iotjs/gulpfile.js | 49 ++++++++++++++++++++++ src/js/iotjs/orig/entry.js | 54 ++++++++++++++++++++++++ src/js/iotjs/orig/slot.js | 10 +++++ src/js/iotjs/package.json | 32 ++++++++++++++ src/js/iotjs/src/entry.js | 72 ++++++++++++++++++++++++++++++++ src/js/iotjs/src/iotstring.js | 66 +++++++++++++++++++++++++++++ src/js/iotjs/src/liveness.js | 5 +++ src/js/iotjs/src/main.js | 67 +++++++++++++++++++++++++++++ src/js/iotjs/src/pair.js | 32 ++++++++++++++ src/js/iotjs/src/slot.js | 0 src/js/iotjs/test/test.js | 6 +++ 20 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 src/js/iotjs/.babelrc create mode 100644 src/js/iotjs/.bowerrc create mode 100644 src/js/iotjs/.editorconfig create mode 100644 src/js/iotjs/.jshintrc create mode 100644 src/js/iotjs/README.md create mode 100644 src/js/iotjs/bower.json create mode 100644 src/js/iotjs/examples/index.html create mode 100644 src/js/iotjs/gulpfile.js create mode 100644 src/js/iotjs/orig/entry.js create mode 100644 src/js/iotjs/orig/slot.js create mode 100644 src/js/iotjs/package.json create mode 100644 src/js/iotjs/src/entry.js create mode 100644 src/js/iotjs/src/iotstring.js create mode 100644 src/js/iotjs/src/liveness.js create mode 100644 src/js/iotjs/src/main.js create mode 100644 src/js/iotjs/src/pair.js create mode 100644 src/js/iotjs/src/slot.js create mode 100644 src/js/iotjs/test/test.js diff --git a/.gitignore b/.gitignore index 68a8b77..b28f4ad 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ build/ compiled/ *.o *~ +/src/js/iotjs/node_modules/ +node_modules/ +dist/ +bower_components +test/bower_components diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index 4db9133..ed577a6 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -19,7 +19,7 @@ class Slot implements Liveness { static final int HMAC_SIZE=32; /** Sequence number of the slot. */ - private long seqnum; + private long seqnum;// /** HMAC of previous slot. */ private byte[] prevhmac; /** HMAC of this slot. */ diff --git a/src/js/iotjs/.babelrc b/src/js/iotjs/.babelrc new file mode 100644 index 0000000..9d8d516 --- /dev/null +++ b/src/js/iotjs/.babelrc @@ -0,0 +1 @@ +{ "presets": ["es2015"] } diff --git a/src/js/iotjs/.bowerrc b/src/js/iotjs/.bowerrc new file mode 100644 index 0000000..baa91a3 --- /dev/null +++ b/src/js/iotjs/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} \ No newline at end of file diff --git a/src/js/iotjs/.editorconfig b/src/js/iotjs/.editorconfig new file mode 100644 index 0000000..e717f5e --- /dev/null +++ b/src/js/iotjs/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/src/js/iotjs/.jshintrc b/src/js/iotjs/.jshintrc new file mode 100644 index 0000000..0959e67 --- /dev/null +++ b/src/js/iotjs/.jshintrc @@ -0,0 +1,20 @@ +{ + "node": true, + "esnext": true, + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "indent": 2, + "latedef": true, + "newcap": true, + "noarg": true, + "quotmark": "single", + "regexp": true, + "undef": true, + "unused": true, + "trailing": true, + "smarttabs": true, + "white": true +} diff --git a/src/js/iotjs/README.md b/src/js/iotjs/README.md new file mode 100644 index 0000000..2e6e0a1 --- /dev/null +++ b/src/js/iotjs/README.md @@ -0,0 +1,21 @@ +iotjs +================================================== + +What does your library do? + +Getting Started +-------------------------------------- + +- Install dependencies: `npm install` +- Run `bower install` to install frontend dependencies +- Run `gulp` to build your library + +Usage +-------------------------------------- + +How can I use it? + +Future Development +-------------------------------------- + +What would you like to do but don't have the time for? diff --git a/src/js/iotjs/bower.json b/src/js/iotjs/bower.json new file mode 100644 index 0000000..cb33217 --- /dev/null +++ b/src/js/iotjs/bower.json @@ -0,0 +1,6 @@ +{ + "name": "iotjs", + "version": "0.0.0", + "dependencies": {} +} + diff --git a/src/js/iotjs/examples/index.html b/src/js/iotjs/examples/index.html new file mode 100644 index 0000000..8613e8e --- /dev/null +++ b/src/js/iotjs/examples/index.html @@ -0,0 +1,11 @@ + + + + + iotjs Example + + + + + + \ No newline at end of file diff --git a/src/js/iotjs/gulpfile.js b/src/js/iotjs/gulpfile.js new file mode 100644 index 0000000..ed79d92 --- /dev/null +++ b/src/js/iotjs/gulpfile.js @@ -0,0 +1,49 @@ +var gulp = require('gulp'); +var gulpif = require('gulp-if'); +var clean = require('gulp-clean'); +var order = require('gulp-order'); +var rename = require('gulp-rename'); +var concat = require('gulp-concat'); +var jshint = require('gulp-jshint'); +var uglify = require('gulp-uglify'); +var stylish = require('jshint-stylish'); +var livereload = require('gulp-livereload'); +var sourcemaps = require('gulp-sourcemaps'); +var flags = require('minimist')(process.argv.slice(2)); + +// Gulp command line arguments +var production = flags.production || false; +var debug = flags.debug || !production; +var watch = flags.watch; + +gulp.task('build', ['clean'], function() { + // Single entry point to browserify + gulp.src(['src/*.js', 'vendor/*.js']) + .pipe(order([ // The order of concatenation + 'src/main.js' + ], {base: '.'})) + .pipe(gulpif(debug, sourcemaps.init())) + .pipe(gulpif(production, uglify())) + .pipe(concat('iotjs.js')) + .pipe(gulpif(debug, sourcemaps.write())) + .pipe(gulp.dest('./build/')) + .pipe(gulpif(watch, livereload())); +}); + +gulp.task('lint', function() { + return gulp.src('src/*.js') + .pipe(jshint()) + .pipe(jshint.reporter(stylish)) +}); + +gulp.task('clean', function() { + return gulp.src(['./build'], {read: false}) + .pipe(clean({force: true})); +}); + +gulp.task('watch', function() { + livereload.listen(); + gulp.watch('src/*', ['lint', 'build']); +}); + +gulp.task('default', ['clean', 'lint', 'build']); diff --git a/src/js/iotjs/orig/entry.js b/src/js/iotjs/orig/entry.js new file mode 100644 index 0000000..8ad481a --- /dev/null +++ b/src/js/iotjs/orig/entry.js @@ -0,0 +1,54 @@ +class Entry{ + constructor(slot) { + if (slot && slot instanceof Slot) { + + this.TypeKeyValue = 1; + this.TypeLastmessage = 2; + this.TypeRejectedMessage = 3; + this.TypeTableStatus = 4; + this.liveStatus = true; + this.parentslot = slot; + + } + } + static decode(slot, bytebuffer) { + if (slot instanceof Slot && bytebuffer instanceof ByteBuffer) { + var type = bytebuffer.readByte(); + switch (type) { + case this.TypeKeyValue: + return KeyValue.decode(slot, bytebuffer); + case this.TypeLastmessage: + return LastMessage.decode(slot, bytebuffer); + case this.TypeRejectedMessage: + return RejectedMessage.decode(slot, bytebuffer); + case this.TypeTableStatus: + return TableStatus.decode(slot, bytebuffer); + default: + throw new Error("Unrecognized Entry Type: " + type); + } + } + } + isLive(){ + return this.liveStatus; + } + setDead() { + this.liveStatus = false; + parentslot.decrementLiveCount(); + } + + //must be overriden. + encode(bytebuffer){ + + } + getSize(){ + + } + getType(){ + + } + getCopy(slot){ + if(slot && slot instanceof Slot){ + + } + } +} \ No newline at end of file diff --git a/src/js/iotjs/orig/slot.js b/src/js/iotjs/orig/slot.js new file mode 100644 index 0000000..72352d9 --- /dev/null +++ b/src/js/iotjs/orig/slot.js @@ -0,0 +1,10 @@ +class Slot{ + constructor(seqnum,machineid,prevhmac,hmac){ + this.SLOT_SIZE=2048; + this.RESERVED_SPACE=64; + this.HMAC_SIZE=32; + (typeof seqnum === "number")? this.seqnum = seqnum : throw new Error("seqnum should be a number"); + (typeof machineid === "number")? this.machineid = seqnum : throw new Error("seqnum should be a number"); + + } +} \ No newline at end of file diff --git a/src/js/iotjs/package.json b/src/js/iotjs/package.json new file mode 100644 index 0000000..2b12bbe --- /dev/null +++ b/src/js/iotjs/package.json @@ -0,0 +1,32 @@ +{ + "name": "iotjs", + "version": "0.0.0", + "scripts": { + "test": "gulp && node ./test/test.js" + }, + "dependencies": { + "bytebuffer": "^5.0.1", + "crypto-js": "^3.1.6", + "gulp": "3.8.11", + "gulp-clean": "0.3.1", + "gulp-concat": "2.5.2", + "gulp-if": "1.2.5", + "gulp-jshint": "1.9.4", + "gulp-livereload": "3.8.0", + "gulp-load-plugins": "0.8.1", + "gulp-order": "1.1.1", + "gulp-rename": "1.2.0", + "gulp-sourcemaps": "1.5.1", + "gulp-uglify": "1.1.0", + "jshint-stylish": "1.0.1", + "minimist": "1.1.1", + "object-hash": "^1.1.3", + "request": "^2.74.0", + "underscore": "^1.8.3" + }, + "devDependencies": { + "babel-cli": "^6.11.4", + "babel-preset-es2015": "^6.9.0", + "browserify": "^13.1.0" + } +} diff --git a/src/js/iotjs/src/entry.js b/src/js/iotjs/src/entry.js new file mode 100644 index 0000000..e4a47a3 --- /dev/null +++ b/src/js/iotjs/src/entry.js @@ -0,0 +1,72 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Entry = function () { + function Entry(slot) { + _classCallCheck(this, Entry); + + if (slot && slot instanceof Slot) { + + this.TypeKeyValue = 1; + this.TypeLastmessage = 2; + this.TypeRejectedMessage = 3; + this.TypeTableStatus = 4; + this.liveStatus = true; + this.parentslot = slot; + } + } + + _createClass(Entry, [{ + key: "isLive", + value: function isLive() { + return this.liveStatus; + } + }, { + key: "setDead", + value: function setDead() { + this.liveStatus = false; + parentslot.decrementLiveCount(); + } + + //must be overriden. + + }, { + key: "encode", + value: function encode(bytebuffer) {} + }, { + key: "getSize", + value: function getSize() {} + }, { + key: "getType", + value: function getType() {} + }, { + key: "getCopy", + value: function getCopy(slot) { + if (slot && slot instanceof Slot) {} + } + }], [{ + key: "decode", + value: function decode(slot, bytebuffer) { + if (slot instanceof Slot && bytebuffer instanceof ByteBuffer) { + var type = bytebuffer.readByte(); + switch (type) { + case this.TypeKeyValue: + return KeyValue.decode(slot, bytebuffer); + case this.TypeLastmessage: + return LastMessage.decode(slot, bytebuffer); + case this.TypeRejectedMessage: + return RejectedMessage.decode(slot, bytebuffer); + case this.TypeTableStatus: + return TableStatus.decode(slot, bytebuffer); + default: + throw new Error("Unrecognized Entry Type: " + type); + } + } + } + }]); + + return Entry; +}(); \ No newline at end of file diff --git a/src/js/iotjs/src/iotstring.js b/src/js/iotjs/src/iotstring.js new file mode 100644 index 0000000..05f35dc --- /dev/null +++ b/src/js/iotjs/src/iotstring.js @@ -0,0 +1,66 @@ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var IoTString = function () { + function IoTString(arg) { + _classCallCheck(this, IoTString); + + if (arg === undefined) { + this.array = new Uint8Array(); + this.hashcode; + } else if (arg && typeof arg === "string") { + this.array = new Uint8Array(arg.length); + for (var i = 0; i < arg.length; ++i) { + this.array[i] = arg.charCodeAt(i); + } + this.hashcode = hash(this.array); + } else if (arg && arg instanceof Uint8Array) { + this.array = arg; + this.hashcode = hashcode(arg); + } + } + + _createClass(IoTString, [{ + key: "shallow", + value: function shallow(arg) { + if (arg && arg instanceof Uint8Array) { + var i = new IotString(arg); + return i; + } + } + }, { + key: "internalBytes", + value: function internalBytes() { + return this.array; + } + }, { + key: "hashCode", + value: function hashCode() { + return this.hashcode; + } + }, { + key: "toString", + value: function toString() { + return this.array.toString(); + } + }, { + key: "getBytes", + value: function getBytes() { + var obj; + return _.extend(obj, this.array); + } + }, { + key: "equals", + value: function equals(arr) { + return _.isEqual(arr, this.array); + } + }, { + key: "length", + value: function length() { + return this.array.length; + } + }]); + + return IoTString; +}(); \ No newline at end of file diff --git a/src/js/iotjs/src/liveness.js b/src/js/iotjs/src/liveness.js new file mode 100644 index 0000000..22cbd3f --- /dev/null +++ b/src/js/iotjs/src/liveness.js @@ -0,0 +1,5 @@ +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Liveness = function Liveness() { + _classCallCheck(this, Liveness); +}; \ No newline at end of file diff --git a/src/js/iotjs/src/main.js b/src/js/iotjs/src/main.js new file mode 100644 index 0000000..78e6a07 --- /dev/null +++ b/src/js/iotjs/src/main.js @@ -0,0 +1,67 @@ +/* jshint devel:true */ +"use strict"; +console.log('Welcome to iotjs-www','\n\n'); + +// set up the base line.. +// Using browserify to set up browser exports +var crypto = require('crypto-js'); +var hash = require('object-hash'); +var _ = require('underscore'); +var ByteBuffer = require("bytebuffer"); + + +(function() { + + var root = this; + + + // iot namespace main constructor + var iot = function(obj) { + if (obj instanceof iot) return obj; + if (!(this instanceof iot)) return new iot(obj); + this.iot = obj; + }; + + // export iot to the global exports + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = iot; + } + exports.iot = iot; + } else { + root.iot = iot; + } + + iot.baselinetest = function(){ + // baseline test + console.log('its alive!!!'); + console.log(); + + //local hash test + console.log(hash('hello man')); + console.log(typeof hash('hello man')); + console.log(); + + //Pair test + var p = new Pair(1,2); + console.log(p.toString()); + console.log(); + + //iotstring test + var i = new IoTString('hello'); + console.log(i.length()); + console.log(); + } + + + + + + + + + + + + +}()) \ No newline at end of file diff --git a/src/js/iotjs/src/pair.js b/src/js/iotjs/src/pair.js new file mode 100644 index 0000000..e2467e3 --- /dev/null +++ b/src/js/iotjs/src/pair.js @@ -0,0 +1,32 @@ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Pair = function () { + function Pair(a, b) { + _classCallCheck(this, Pair); + + this.a = a; + this.b = b; + } + + _createClass(Pair, [{ + key: 'getFirst', + value: function getFirst() { + return this.a; + } + }, { + key: 'getSecond', + value: function getSecond() { + return this.b; + } + }, { + key: 'toString', + value: function toString() { + var str = '<' + this.a + ',' + this.b + '>'; + return str; + } + }]); + + return Pair; +}(); \ No newline at end of file diff --git a/src/js/iotjs/src/slot.js b/src/js/iotjs/src/slot.js new file mode 100644 index 0000000..e69de29 diff --git a/src/js/iotjs/test/test.js b/src/js/iotjs/test/test.js new file mode 100644 index 0000000..7d78e72 --- /dev/null +++ b/src/js/iotjs/test/test.js @@ -0,0 +1,6 @@ +var iot = require('../build/iotjs.js'); + +iot.baselinetest(); + + + -- 2.34.1 From 5a7899c7f25ce7d0f80f15c749128ec755900c0a Mon Sep 17 00:00:00 2001 From: joelbandi Date: Tue, 26 Jul 2016 05:59:41 -0700 Subject: [PATCH 02/16] modded gitignore to get rid of annoying .sty files --- .gitignore | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index b28f4ad..6e6fb00 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,19 @@ node_modules/ dist/ bower_components test/bower_components + + +# Joel Bandi says : Some tex dependencies i had to locally download ..please ignore this +doc/README +doc/algc.sty +doc/algcompatible.sty +doc/algmatlab.sty +doc/algorithmicx.pdf +doc/algorithmicx.sty +doc/algorithmicx.tex +doc/algpascal.sty +doc/algpseudocode.sty +doc/iotcloud.aux +doc/iotcloud.log +doc/iotcloud.pdf + -- 2.34.1 From a58d3a3a3a51e36f3c29a3817e765f1c2516cd90 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Tue, 26 Jul 2016 16:26:33 -0700 Subject: [PATCH 03/16] add crypt to slots --- src/java/iotcloud/CloudComm.java | 69 ++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/src/java/iotcloud/CloudComm.java b/src/java/iotcloud/CloudComm.java index b5aca62..49217ec 100644 --- a/src/java/iotcloud/CloudComm.java +++ b/src/java/iotcloud/CloudComm.java @@ -16,12 +16,13 @@ import java.security.SecureRandom; class CloudComm { String baseurl; - Cipher encryptcipher; - Cipher decryptcipher; + Cipher encryptCipher; + Cipher decryptCipher; Mac mac; - byte[] salt; - SecretKeySpec key; + String password; + SecureRandom random; static final int SALT_SIZE = 8; + static final int IV_SIZE = 16; /** * Empty Constructor needed for child class. @@ -34,21 +35,21 @@ class CloudComm { * Constructor for actual use. Takes in the url and password. */ - CloudComm(String _baseurl, String password) { + CloudComm(String _baseurl, String _password) { this.baseurl=_baseurl; - initCloud(password); + this.password = _password; + this.random = new SecureRandom(); } /** * Generates Key from password. */ - private void initKey(String password) { + private SecretKeySpec initKey(byte[] salt) { try { - salt=new byte[SALT_SIZE]; PBEKeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); SecretKey tmpkey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(keyspec); - this.key = new SecretKeySpec(tmpkey.getEncoded(), "AES"); + return new SecretKeySpec(tmpkey.getEncoded(), "AES"); } catch (Exception e) { e.printStackTrace(); throw new Error("Failed generating key."); @@ -59,11 +60,27 @@ class CloudComm { * Inits the HMAC generator. */ - private void initCloud(String password) { + private byte[] initCrypt(byte[] salt) { try { - initKey(password); + SecretKeySpec key=initKey(salt); mac = Mac.getInstance("HmacSHA256"); mac.init(key); + encryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding"); + encryptCipher.init(Cipher.ENCRYPT_MODE, key); + return encryptCipher.getIV(); + } catch (Exception e) { + e.printStackTrace(); + throw new Error("Failed To Initialize Ciphers"); + } + } + + private void initDeCrypt(byte[] salt, byte[] iv) { + try { + SecretKeySpec key=initKey(salt); + mac = Mac.getInstance("HmacSHA256"); + mac.init(key); + Cipher decryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding"); + decryptCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); } catch (Exception e) { e.printStackTrace(); throw new Error("Failed To Initialize Ciphers"); @@ -91,8 +108,11 @@ class CloudComm { public Slot[] putSlot(Slot slot, int max) { try { long sequencenumber=slot.getSequenceNumber(); + byte[] salt=new byte[SALT_SIZE]; + random.nextBytes(salt); + byte[] iv=initCrypt(salt); + byte[] bytes=slot.encode(mac); - URL url=buildRequest(true, sequencenumber, max); URLConnection con=url.openConnection(); HttpURLConnection http = (HttpURLConnection) con; @@ -100,7 +120,11 @@ class CloudComm { http.setFixedLengthStreamingMode(bytes.length); http.setDoOutput(true); http.connect(); + OutputStream os=http.getOutputStream(); + os.write(salt); + os.write(iv); + bytes = encryptCipher.doFinal(bytes); os.write(bytes); InputStream is=http.getInputStream(); @@ -118,15 +142,6 @@ class CloudComm { } } - /* - Cipher encryptCipher = - Cipher.getInstance("AES/CBC/PKCS5Padding"); - encryptCipher.init(Cipher.ENCRYPT_MODE, secret); - Cipher decryptCipher = - Cipher.getInstance("AES/CBC/PKCS5Padding"); - decryptCipher.init(Cipher.DECRYPT_MODE, secret); - */ - /** * Request the server to send all slots with the given * sequencenumber or newer. @@ -142,6 +157,7 @@ class CloudComm { InputStream is=http.getInputStream(); DataInputStream dis=new DataInputStream(is); + byte[] resptype=new byte[7]; dis.readFully(resptype); if (!Arrays.equals(resptype, "getslot".getBytes())) @@ -158,7 +174,7 @@ class CloudComm { * server response. Shared by both putSlot and getSlots. */ - private Slot[] processSlots(DataInputStream dis) throws IOException { + private Slot[] processSlots(DataInputStream dis) throws Exception { int numberofslots=dis.readInt(); int[] sizesofslots=new int[numberofslots]; Slot[] slots=new Slot[numberofslots]; @@ -166,8 +182,17 @@ class CloudComm { sizesofslots[i]=dis.readInt(); for(int i=0; i Date: Tue, 26 Jul 2016 18:37:50 -0700 Subject: [PATCH 04/16] Add support for salts and crypto --- src/java/iotcloud/CloudComm.java | 99 +++++++++++++++++++++----------- src/java/iotcloud/Table.java | 1 + src/java/iotcloud/issues.txt | 3 +- src/server/iotquery.cpp | 78 +++++++++++++++++++++++-- src/server/iotquery.h | 7 +++ 5 files changed, 145 insertions(+), 43 deletions(-) diff --git a/src/java/iotcloud/CloudComm.java b/src/java/iotcloud/CloudComm.java index 49217ec..964b7c0 100644 --- a/src/java/iotcloud/CloudComm.java +++ b/src/java/iotcloud/CloudComm.java @@ -22,8 +22,8 @@ class CloudComm { String password; SecureRandom random; static final int SALT_SIZE = 8; - static final int IV_SIZE = 16; - + byte salt[]; + /** * Empty Constructor needed for child class. */ @@ -45,7 +45,7 @@ class CloudComm { * Generates Key from password. */ - private SecretKeySpec initKey(byte[] salt) { + private SecretKeySpec initKey() { try { PBEKeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); SecretKey tmpkey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(keyspec); @@ -60,27 +60,16 @@ class CloudComm { * Inits the HMAC generator. */ - private byte[] initCrypt(byte[] salt) { + private void initCrypt() { try { - SecretKeySpec key=initKey(salt); + SecretKeySpec key=initKey(); + password = null; // drop password mac = Mac.getInstance("HmacSHA256"); mac.init(key); - encryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding"); + encryptCipher =Cipher.getInstance("AES/ECB/PKCS5Padding"); encryptCipher.init(Cipher.ENCRYPT_MODE, key); - return encryptCipher.getIV(); - } catch (Exception e) { - e.printStackTrace(); - throw new Error("Failed To Initialize Ciphers"); - } - } - - private void initDeCrypt(byte[] salt, byte[] iv) { - try { - SecretKeySpec key=initKey(salt); - mac = Mac.getInstance("HmacSHA256"); - mac.init(key); - Cipher decryptCipher =Cipher.getInstance("AES/CBC/PKCS5Padding"); - decryptCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); + decryptCipher =Cipher.getInstance("AES/ECB/PKCS5Padding"); + decryptCipher.init(Cipher.DECRYPT_MODE, key); } catch (Exception e) { e.printStackTrace(); throw new Error("Failed To Initialize Ciphers"); @@ -98,33 +87,72 @@ class CloudComm { urlstr += "&max="+maxentries; return new URL(urlstr); } + + public void setSalt() { + try { + salt = new byte[SALT_SIZE]; + random.nextBytes(salt); + URL url=new URL(baseurl+"?req=setsalt"); + URLConnection con=url.openConnection(); + HttpURLConnection http = (HttpURLConnection) con; + http.setRequestMethod("POST"); + http.setFixedLengthStreamingMode(salt.length); + http.setDoOutput(true); + http.connect(); + OutputStream os=http.getOutputStream(); + os.write(salt); + int responsecode=http.getResponseCode(); + if (responsecode != HttpURLConnection.HTTP_OK) + throw new Error("Invalid response"); + } catch (Exception e) { + e.printStackTrace(); + throw new Error("Failed setting salt"); + } + initCrypt(); + } + private void getSalt() throws Exception { + URL url=new URL(baseurl+"?req=getsalt"); + URLConnection con=url.openConnection(); + HttpURLConnection http = (HttpURLConnection) con; + http.setRequestMethod("POST"); + http.connect(); + + InputStream is=http.getInputStream(); + DataInputStream dis=new DataInputStream(is); + int salt_length=dis.readInt(); + byte [] tmp=new byte[salt_length]; + dis.readFully(tmp); + salt=tmp; + } + /* * API for putting a slot into the queue. Returns null on success. * On failure, the server will send slots with newer sequence * numbers. */ - public Slot[] putSlot(Slot slot, int max) { + Slot[] putSlot(Slot slot, int max) { try { - long sequencenumber=slot.getSequenceNumber(); - byte[] salt=new byte[SALT_SIZE]; - random.nextBytes(salt); - byte[] iv=initCrypt(salt); + if (salt == null) { + getSalt(); + initCrypt(); + } + long sequencenumber=slot.getSequenceNumber(); byte[] bytes=slot.encode(mac); + bytes = encryptCipher.doFinal(bytes); + URL url=buildRequest(true, sequencenumber, max); URLConnection con=url.openConnection(); HttpURLConnection http = (HttpURLConnection) con; + http.setRequestMethod("POST"); http.setFixedLengthStreamingMode(bytes.length); http.setDoOutput(true); http.connect(); OutputStream os=http.getOutputStream(); - os.write(salt); - os.write(iv); - bytes = encryptCipher.doFinal(bytes); os.write(bytes); InputStream is=http.getInputStream(); @@ -138,6 +166,7 @@ class CloudComm { else throw new Error("Bad response to putslot"); } catch (Exception e) { + e.printStackTrace(); throw new Error("putSlot failed"); } } @@ -147,8 +176,13 @@ class CloudComm { * sequencenumber or newer. */ - public Slot[] getSlots(long sequencenumber) { + Slot[] getSlots(long sequencenumber) { try { + if (salt == null) { + getSalt(); + initCrypt(); + } + URL url=buildRequest(false, sequencenumber, 0); URLConnection con=url.openConnection(); HttpURLConnection http = (HttpURLConnection) con; @@ -165,6 +199,7 @@ class CloudComm { else return processSlots(dis); } catch (Exception e) { + e.printStackTrace(); throw new Error("getSlots failed"); } } @@ -182,12 +217,6 @@ class CloudComm { sizesofslots[i]=dis.readInt(); for(int i=0; i Date: Tue, 26 Jul 2016 22:03:57 -0700 Subject: [PATCH 05/16] change resize algorithm and slot usage --- src/java/iotcloud/CloudComm.java | 6 +- src/java/iotcloud/Slot.java | 31 ++++----- src/java/iotcloud/Table.java | 114 +++++++++++++++++++++---------- 3 files changed, 95 insertions(+), 56 deletions(-) diff --git a/src/java/iotcloud/CloudComm.java b/src/java/iotcloud/CloudComm.java index 964b7c0..ac906b1 100644 --- a/src/java/iotcloud/CloudComm.java +++ b/src/java/iotcloud/CloudComm.java @@ -23,6 +23,7 @@ class CloudComm { SecureRandom random; static final int SALT_SIZE = 8; byte salt[]; + Table table; /** * Empty Constructor needed for child class. @@ -35,7 +36,8 @@ class CloudComm { * Constructor for actual use. Takes in the url and password. */ - CloudComm(String _baseurl, String _password) { + CloudComm(Table _table, String _baseurl, String _password) { + this.table=_table; this.baseurl=_baseurl; this.password = _password; this.random = new SecureRandom(); @@ -222,7 +224,7 @@ class CloudComm { data = decryptCipher.doFinal(data); - slots[i]=Slot.decode(data, mac); + slots[i]=Slot.decode(table, data, mac); } dis.close(); return slots; diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index ed577a6..c22d0d9 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -13,8 +13,6 @@ import java.util.Arrays; class Slot implements Liveness { /** Sets the slot size. */ static final int SLOT_SIZE=2048; - /** Sets how many bytes we reserve. */ - static final int RESERVED_SPACE=64; /** Sets the size for the HMAC. */ static final int HMAC_SIZE=32; @@ -35,8 +33,10 @@ class Slot implements Liveness { private boolean seqnumlive; /** Number of bytes of free space. */ private int freespace; + /** Reference to Table */ + private Table table; - Slot(long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac) { + Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac) { seqnum=_seqnum; machineid=_machineid; prevhmac=_prevhmac; @@ -45,14 +45,15 @@ class Slot implements Liveness { livecount=1; seqnumlive=true; freespace = SLOT_SIZE - getBaseSize(); + table=_table; } - Slot(long _seqnum, long _machineid, byte[] _prevhmac) { - this(_seqnum, _machineid, _prevhmac, null); + Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac) { + this(_table, _seqnum, _machineid, _prevhmac, null); } - Slot(long _seqnum, long _machineid) { - this(_seqnum, _machineid, new byte[HMAC_SIZE], null); + Slot(Table _table, long _seqnum, long _machineid) { + this(_table, _seqnum, _machineid, new byte[HMAC_SIZE], null); } byte[] getHMAC() { @@ -81,15 +82,6 @@ class Slot implements Liveness { * using its reserved space. */ boolean hasSpace(Entry e) { - int newfreespace = freespace - e.getSize(); - return newfreespace > RESERVED_SPACE; - } - - /** - * Returns true if the slot can fit the entry potentially using the - * reserved space. */ - - boolean canFit(Entry e) { int newfreespace = freespace - e.getSize(); return newfreespace >= 0; } @@ -98,7 +90,7 @@ class Slot implements Liveness { return entries; } - static Slot decode(byte[] array, Mac mac) { + static Slot decode(Table table, byte[] array, Mac mac) { mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE); byte[] realmac=mac.doFinal(); @@ -113,7 +105,7 @@ class Slot implements Liveness { long seqnum=bb.getLong(); long machineid=bb.getLong(); int numentries=bb.getInt(); - Slot slot=new Slot(seqnum, machineid, prevhmac, hmac); + Slot slot=new Slot(table, seqnum, machineid, prevhmac, hmac); for(int i=0; i e=getLiveEntries(); + if (livecount==0) + table.decrementLiveCount(); } /** diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index 028025f..9e18553 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -5,6 +5,7 @@ import java.util.Iterator; import java.util.HashSet; import java.util.Arrays; import java.util.Vector; +import java.util.Random; /** * IoTTable data structure. Provides client inferface. @@ -12,7 +13,6 @@ import java.util.Vector; * @version 1.0 */ - final public class Table { private int numslots; private HashMap table=new HashMap(); @@ -24,20 +24,30 @@ final public class Table { private long localmachineid; private TableStatus lastTableStatus; static final int FREE_SLOTS = 10; - static final int FORCED_RESIZE_INCREMENT = 20; - + static final int SKIP_THRESHOLD = 10; + private long liveslotcount=0; + private int chance; + static final double RESIZE_MULTIPLE = 1.2; + static final double RESIZE_THRESHOLD = 0.75; + private int resizethreshold; + private long lastliveslotseqn; + private Random random; + public Table(String baseurl, String password, long _localmachineid) { localmachineid=_localmachineid; buffer = new SlotBuffer(); numslots = buffer.capacity(); + setResizeThreshold(); sequencenumber = 0; - cloud=new CloudComm(baseurl, password); + cloud=new CloudComm(this, baseurl, password); + lastliveslotseqn = 1; } public Table(CloudComm _cloud, long _localmachineid) { localmachineid=_localmachineid; buffer = new SlotBuffer(); numslots = buffer.capacity(); + setResizeThreshold(); sequencenumber = 0; cloud=_cloud; } @@ -63,7 +73,7 @@ final public class Table { public void initTable() { cloud.setSalt();//Set the salt - Slot s=new Slot(1, localmachineid); + Slot s=new Slot(this, 1, localmachineid); TableStatus status=new TableStatus(s, numslots); s.addEntry(status); Slot[] array=cloud.putSlot(s, numslots); @@ -92,37 +102,61 @@ final public class Table { } } - private boolean tryput(IoTString key, IoTString value, boolean forcedresize) { - Slot s=new Slot(sequencenumber+1, localmachineid, buffer.getSlot(sequencenumber).getHMAC()); - long seqn = buffer.getOldestSeqNum(); + void decrementLiveCount() { + liveslotcount--; + } + + private void setResizeThreshold() { + int resize_lower=(int) RESIZE_THRESHOLD * numslots; + resizethreshold=resize_lower-1+random.nextInt(numslots-resize_lower); + } + + private boolean tryput(IoTString key, IoTString value, boolean resize) { + Slot s=new Slot(this, sequencenumber+1, localmachineid, buffer.getSlot(sequencenumber).getHMAC()); + int newsize = 0; + if (liveslotcount > resizethreshold) { + resize=true; + newsize = (int) (numslots * RESIZE_MULTIPLE); + } - if (forcedresize) { - TableStatus status=new TableStatus(s, FORCED_RESIZE_INCREMENT + numslots); + + if (resize) { + newsize = (int) (numslots * RESIZE_MULTIPLE); + TableStatus status=new TableStatus(s, newsize); s.addEntry(status); } - if ((numslots - buffer.size()) < FREE_SLOTS) { - /* have to check whether we have enough free slots */ - long fullfirstseqn = buffer.getNewestSeqNum() + 1 - numslots; - seqn = fullfirstseqn < 1?1:fullfirstseqn; - for(int i=0; i < FREE_SLOTS; i++, seqn++) { - Slot prevslot=buffer.getSlot(seqn); - if (!prevslot.isLive()) - continue; - Vector liveentries = prevslot.getLiveEntries(); - for(Entry liveentry:liveentries) { - if (s.hasSpace(liveentry)) - s.addEntry(liveentry); - else if (i==0) { - if (s.canFit(liveentry)) - s.addEntry(liveentry); - else if (!forcedresize) { - return tryput(key, value, true); - } + long newestseqnum = buffer.getNewestSeqNum(); + long oldestseqnum = buffer.getOldestSeqNum(); + if (lastliveslotseqn < oldestseqnum) + lastliveslotseqn = oldestseqnum; + + long seqn = lastliveslotseqn; + boolean seenliveslot = false; + long firstiffull = newestseqnum + 1 - numslots; + long threshold = firstiffull + FREE_SLOTS; + + for(; seqn < threshold; seqn++) { + Slot prevslot=buffer.getSlot(seqn); + //Push slot number forward + if (!seenliveslot) + lastliveslotseqn = seqn; + + if (!prevslot.isLive()) + continue; + seenliveslot = true; + Vector liveentries = prevslot.getLiveEntries(); + for(Entry liveentry:liveentries) { + if (s.hasSpace(liveentry)) { + s.addEntry(liveentry); + } else if (seqn==firstiffull) { + if (!resize) { + return tryput(key, value, true); } } } } + KeyValue kv=new KeyValue(s, key, value); boolean insertedkv=false; if (s.hasSpace(kv)) { @@ -130,24 +164,32 @@ final public class Table { insertedkv=true; } - long newestseqnum=buffer.getNewestSeqNum(); -search: - for(; seqn<=newestseqnum; seqn++) { + int skipcount=0; + search: + for(; seqn <= newestseqnum; seqn++) { Slot prevslot=buffer.getSlot(seqn); + //Push slot number forward + if (!seenliveslot) + lastliveslotseqn = seqn; + if (!prevslot.isLive()) continue; + seenliveslot = true; Vector liveentries = prevslot.getLiveEntries(); for(Entry liveentry:liveentries) { if (s.hasSpace(liveentry)) s.addEntry(liveentry); - else - break search; + else { + skipcount++; + if (skipcount > SKIP_THRESHOLD) + break search; + } } } int max=0; - if (forcedresize) - max = numslots + FORCED_RESIZE_INCREMENT; + if (resize) + max = newsize; Slot[] array=cloud.putSlot(s, max); if (array == null) array = new Slot[] {s}; @@ -193,6 +235,7 @@ search: /* Commit new to slots. */ for(Slot slot:newslots) { buffer.putSlot(slot); + liveslotcount++; } sequencenumber = newslots[newslots.length - 1].getSequenceNumber(); } @@ -225,6 +268,7 @@ search: buffer.resize(currmaxsize); numslots=currmaxsize; + setResizeThreshold(); } private void processEntry(KeyValue entry, SlotIndexer indexer) { -- 2.34.1 From f80cc30f294899f47cef3507334f8ca357862e5e Mon Sep 17 00:00:00 2001 From: Brian Demsky Date: Tue, 26 Jul 2016 22:39:24 -0700 Subject: [PATCH 06/16] bug fixes --- src/java/iotcloud/Slot.java | 10 ++++++---- src/java/iotcloud/SlotBuffer.java | 4 ++-- src/java/iotcloud/Table.java | 19 ++++++++++--------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index c22d0d9..d23e5c1 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -149,14 +149,16 @@ class Slot implements Liveness { * itself. */ - Vector getLiveEntries() { + Vector getLiveEntries(boolean resize) { Vector liveEntries=new Vector(); for(Entry entry: entries) { - if (entry.isLive()) - liveEntries.add(entry); + if (entry.isLive()) { + if (!resize || entry.getType() != Entry.TypeTableStatus) + liveEntries.add(entry); + } } - if (seqnumlive) + if (seqnumlive && !resize) liveEntries.add(new LastMessage(this, machineid, seqnum)); return liveEntries; diff --git a/src/java/iotcloud/SlotBuffer.java b/src/java/iotcloud/SlotBuffer.java index 5d51c1d..ac9dee1 100644 --- a/src/java/iotcloud/SlotBuffer.java +++ b/src/java/iotcloud/SlotBuffer.java @@ -42,8 +42,8 @@ class SlotBuffer { index = 0; } array = newarray; - tail = currsize; - head = 0; + tail = 0; + head = currsize; } private void incrementHead() { diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index 9e18553..91ddaca 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -31,7 +31,7 @@ final public class Table { static final double RESIZE_THRESHOLD = 0.75; private int resizethreshold; private long lastliveslotseqn; - private Random random; + private Random random=new Random(); public Table(String baseurl, String password, long _localmachineid) { localmachineid=_localmachineid; @@ -107,7 +107,7 @@ final public class Table { } private void setResizeThreshold() { - int resize_lower=(int) RESIZE_THRESHOLD * numslots; + int resize_lower=(int) (RESIZE_THRESHOLD * numslots); resizethreshold=resize_lower-1+random.nextInt(numslots-resize_lower); } @@ -115,10 +115,10 @@ final public class Table { Slot s=new Slot(this, sequencenumber+1, localmachineid, buffer.getSlot(sequencenumber).getHMAC()); int newsize = 0; if (liveslotcount > resizethreshold) { + System.out.print("A"); resize=true; newsize = (int) (numslots * RESIZE_MULTIPLE); } - if (resize) { newsize = (int) (numslots * RESIZE_MULTIPLE); @@ -145,12 +145,13 @@ final public class Table { if (!prevslot.isLive()) continue; seenliveslot = true; - Vector liveentries = prevslot.getLiveEntries(); + Vector liveentries = prevslot.getLiveEntries(resize); for(Entry liveentry:liveentries) { if (s.hasSpace(liveentry)) { s.addEntry(liveentry); } else if (seqn==firstiffull) { if (!resize) { + System.out.print("B"); return tryput(key, value, true); } } @@ -175,7 +176,7 @@ final public class Table { if (!prevslot.isLive()) continue; seenliveslot = true; - Vector liveentries = prevslot.getLiveEntries(); + Vector liveentries = prevslot.getLiveEntries(resize); for(Entry liveentry:liveentries) { if (s.hasSpace(liveentry)) s.addEntry(liveentry); @@ -217,10 +218,10 @@ final public class Table { HashSet machineSet=new HashSet(lastmessagetable.keySet()); - initExpectedSize(); + initExpectedSize(firstseqnum); for(Slot slot: newslots) { - updateExpectedSize(); processSlot(indexer, slot, acceptupdatestolocal, machineSet); + updateExpectedSize(); } /* If there is a gap, check to see if the server sent us everything. */ @@ -247,8 +248,8 @@ final public class Table { throw new Error("Server Error: Server did not send all slots. Expected: "+expectedsize+" Received:"+numslots); } - private void initExpectedSize() { - long prevslots = sequencenumber; + private void initExpectedSize(long firstsequencenumber) { + long prevslots = firstsequencenumber; expectedsize = (prevslots < ((long) numslots))?(int) prevslots:numslots; currmaxsize = numslots; } -- 2.34.1 From 545b7f8a87845edfec385dde0f14191875e4f466 Mon Sep 17 00:00:00 2001 From: joelbandi Date: Sat, 30 Jul 2016 05:36:22 -0700 Subject: [PATCH 07/16] more js --- src/java/iotcloud/Entry.java | 2 +- src/java/iotcloud/Slot.java | 12 ++++---- src/js/iotjs/orig/slot.js | 58 +++++++++++++++++++++++++++++++----- src/js/iotjs/package.json | 1 + src/js/iotjs/src/main.js | 45 ++++++++++++++-------------- 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/java/iotcloud/Entry.java b/src/java/iotcloud/Entry.java index 70f90ee..5e0f3f8 100644 --- a/src/java/iotcloud/Entry.java +++ b/src/java/iotcloud/Entry.java @@ -29,7 +29,7 @@ abstract class Entry implements Liveness { * byte tells the type of entry. */ - static Entry decode(Slot slot, ByteBuffer bb) { + slottatic Entry decode(Slot slot, ByteBuffer bb) { byte type=bb.get(); switch(type) { case TypeKeyValue: diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index ed577a6..1d84baa 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -21,18 +21,18 @@ class Slot implements Liveness { /** Sequence number of the slot. */ private long seqnum;// /** HMAC of previous slot. */ - private byte[] prevhmac; + private byte[] prevhmac;// /** HMAC of this slot. */ - private byte[] hmac; + private byte[] hmac;// /** Machine that sent this slot. */ - private long machineid; + private long machineid;// /** Vector of entries in this slot. */ private Vector entries; /** Pieces of information that are live. */ - private int livecount; + private int livecount;// /** Flag that indicates whether this slot is still live for * recording the machine that sent it. */ - private boolean seqnumlive; + private boolean seqnumlive;// /** Number of bytes of free space. */ private int freespace; @@ -52,7 +52,7 @@ class Slot implements Liveness { } Slot(long _seqnum, long _machineid) { - this(_seqnum, _machineid, new byte[HMAC_SIZE], null); + this(_seqnum, _machineid, new byte[ HMAC_SIZE], null); } byte[] getHMAC() { diff --git a/src/js/iotjs/orig/slot.js b/src/js/iotjs/orig/slot.js index 72352d9..35ca266 100644 --- a/src/js/iotjs/orig/slot.js +++ b/src/js/iotjs/orig/slot.js @@ -1,10 +1,52 @@ -class Slot{ - constructor(seqnum,machineid,prevhmac,hmac){ - this.SLOT_SIZE=2048; - this.RESERVED_SPACE=64; - this.HMAC_SIZE=32; - (typeof seqnum === "number")? this.seqnum = seqnum : throw new Error("seqnum should be a number"); - (typeof machineid === "number")? this.machineid = seqnum : throw new Error("seqnum should be a number"); - +class Slot { + constructor(seqnum, machineid, prevhmac, hmac) { + this.SLOT_SIZE = 2048; + this.RESERVED_SPACE = 64; + this.HMAC_SIZE = 32; + (typeof seqnum === "number") ? this.seqnum = seqnum: throw new Error("seqnum should be a number"); + (typeof machineid === "number") ? this.machineid = seqnum: throw new Error("machine should be a number"); + this.livecount = 1; + this.seqnumlive = true; + (prevhmac && prevhmac instanceof Uint8Array) ? this.prevhmac = prevhmac: this.prevhmac = new Uint8Array(this.HMAC_SIZE)); + (hmac && hmac instanceof Uint8Array) ? this.hmac = hmac: this.hmac = null; + this.entries = []; + this.freespace = this.SLOT_SIZE - getBaseSize(); //??????? + } + getHMAC() { + return this.hmac; + } + getPrevHmac() { + return this.prevhmac; + } + addEntry(entry) { + if (entry && entry instanceof Entry) { + var obj; + this.entries.push(_.extend(obj, entry)); + this.livecount++; + freespace -= entry.getSize(); + } + } + addShallowEntry(entry){ + if(entry && entry instanceof Entry){ + this.entries.push(entry); + this.livecount++; + freespace -= entry.getSize(); + } + } + hasSpace(entry){ + var newfreespace = this.freespace - entry.getSize(); + return newfreespace > this.RESERVED_SPACE; + } + canFit(entry){ + var newfreespace = this.freespace - entry.getSize(); + return newfreespace >= 0; + } + getEntries(){ + return this.entries; + } + static decode(array){ + var cond1 = (array && array instanceof Uint8Array); + if(cond1){ + } } } \ No newline at end of file diff --git a/src/js/iotjs/package.json b/src/js/iotjs/package.json index 2b12bbe..277b0ba 100644 --- a/src/js/iotjs/package.json +++ b/src/js/iotjs/package.json @@ -20,6 +20,7 @@ "gulp-uglify": "1.1.0", "jshint-stylish": "1.0.1", "minimist": "1.1.1", + "node-forge": "^0.6.41", "object-hash": "^1.1.3", "request": "^2.74.0", "underscore": "^1.8.3" diff --git a/src/js/iotjs/src/main.js b/src/js/iotjs/src/main.js index 78e6a07..b4485fd 100644 --- a/src/js/iotjs/src/main.js +++ b/src/js/iotjs/src/main.js @@ -1,27 +1,21 @@ /* jshint devel:true */ "use strict"; -console.log('Welcome to iotjs-www','\n\n'); - +console.log('Welcome to iotjs-www', '\n\n'); // set up the base line.. // Using browserify to set up browser exports var crypto = require('crypto-js'); -var hash = require('object-hash'); var _ = require('underscore'); -var ByteBuffer = require("bytebuffer"); - - +var ByteBuffer = require('bytebuffer'); +var hash = require('object-hash'); +var forge = require('node-forge'); (function() { - var root = this; - - // iot namespace main constructor var iot = function(obj) { if (obj instanceof iot) return obj; if (!(this instanceof iot)) return new iot(obj); this.iot = obj; }; - // export iot to the global exports if (typeof exports !== 'undefined') { if (typeof module !== 'undefined' && module.exports) { @@ -32,36 +26,41 @@ var ByteBuffer = require("bytebuffer"); root.iot = iot; } - iot.baselinetest = function(){ - // baseline test + + iot.baselinetest = function() { + // baseline test console.log('its alive!!!'); console.log(); + //local hash test console.log(hash('hello man')); console.log(typeof hash('hello man')); console.log(); + //Pair test - var p = new Pair(1,2); + var p = new Pair(1, 2); console.log(p.toString()); console.log(); + //iotstring test var i = new IoTString('hello'); console.log(i.length()); console.log(); - } - - - - - - - - - + //local crypto test + var data = [{id: 1}, {id: 2}]; + // Encrypt + var ciphertext = crypto.AES.encrypt(JSON.stringify(data), 'secret key 123'); + // Decrypt + var bytes = crypto.AES.decrypt(ciphertext.toString(), 'secret key 123'); + var decryptedData = JSON.parse(bytes.toString(crypto.enc.Utf8)); + // console.log(decryptedData); + var e = crypto.HmacMD5("Mess", "Secret Passphrase"); + console.log(typeof e.toString()); + } }()) \ No newline at end of file -- 2.34.1 From fefa251339c08f0ecf2e43311c8c2203ac3f10c2 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sun, 31 Jul 2016 22:19:27 -0700 Subject: [PATCH 08/16] revert changes joel made to java files so that they will compile --- src/java/iotcloud/Entry.java | 2 +- src/java/iotcloud/Slot.java | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/java/iotcloud/Entry.java b/src/java/iotcloud/Entry.java index 5e0f3f8..70f90ee 100644 --- a/src/java/iotcloud/Entry.java +++ b/src/java/iotcloud/Entry.java @@ -29,7 +29,7 @@ abstract class Entry implements Liveness { * byte tells the type of entry. */ - slottatic Entry decode(Slot slot, ByteBuffer bb) { + static Entry decode(Slot slot, ByteBuffer bb) { byte type=bb.get(); switch(type) { case TypeKeyValue: diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index c114a87..5828fd3 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -17,20 +17,20 @@ class Slot implements Liveness { static final int HMAC_SIZE=32; /** Sequence number of the slot. */ - private long seqnum;// + private long seqnum; /** HMAC of previous slot. */ - private byte[] prevhmac;// + private byte[] prevhmac; /** HMAC of this slot. */ - private byte[] hmac;// + private byte[] hmac; /** Machine that sent this slot. */ - private long machineid;// + private long machineid; /** Vector of entries in this slot. */ private Vector entries; /** Pieces of information that are live. */ - private int livecount;// + private int livecount; /** Flag that indicates whether this slot is still live for * recording the machine that sent it. */ - private boolean seqnumlive;// + private boolean seqnumlive; /** Number of bytes of free space. */ private int freespace; /** Reference to Table */ @@ -52,13 +52,8 @@ class Slot implements Liveness { this(_table, _seqnum, _machineid, _prevhmac, null); } -<<<<<<< HEAD - Slot(long _seqnum, long _machineid) { - this(_seqnum, _machineid, new byte[ HMAC_SIZE], null); -======= Slot(Table _table, long _seqnum, long _machineid) { this(_table, _seqnum, _machineid, new byte[HMAC_SIZE], null); ->>>>>>> f80cc30f294899f47cef3507334f8ca357862e5e } byte[] getHMAC() { -- 2.34.1 From fe630aba513e44443ce3c2660eebd42f49d9f980 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sun, 31 Jul 2016 22:23:43 -0700 Subject: [PATCH 09/16] remove println --- src/java/iotcloud/Table.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index 91ddaca..3afb1a9 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -115,7 +115,6 @@ final public class Table { Slot s=new Slot(this, sequencenumber+1, localmachineid, buffer.getSlot(sequencenumber).getHMAC()); int newsize = 0; if (liveslotcount > resizethreshold) { - System.out.print("A"); resize=true; newsize = (int) (numslots * RESIZE_MULTIPLE); } -- 2.34.1 From ef2437bed48c4f81b95ebbf0709c226f3f6635ba Mon Sep 17 00:00:00 2001 From: joelbandi Date: Mon, 1 Aug 2016 05:38:00 -0700 Subject: [PATCH 10/16] more js: Slot.js plus dist version --- src/java/iotcloud/Entry.java | 2 +- src/java/iotcloud/Slot.java | 6 +- src/js/iotjs/.jshintrc | 2 - src/js/iotjs/orig/compat.txt | 3 + src/js/iotjs/orig/slot.js | 147 ++++++++++++++++++++++--- src/js/iotjs/src/main.js | 2 +- src/js/iotjs/src/slot.js | 208 +++++++++++++++++++++++++++++++++++ 7 files changed, 347 insertions(+), 23 deletions(-) create mode 100644 src/js/iotjs/orig/compat.txt diff --git a/src/java/iotcloud/Entry.java b/src/java/iotcloud/Entry.java index 5e0f3f8..70f90ee 100644 --- a/src/java/iotcloud/Entry.java +++ b/src/java/iotcloud/Entry.java @@ -29,7 +29,7 @@ abstract class Entry implements Liveness { * byte tells the type of entry. */ - slottatic Entry decode(Slot slot, ByteBuffer bb) { + static Entry decode(Slot slot, ByteBuffer bb) { byte type=bb.get(); switch(type) { case TypeKeyValue: diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index c114a87..2a66fa3 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -52,13 +52,9 @@ class Slot implements Liveness { this(_table, _seqnum, _machineid, _prevhmac, null); } -<<<<<<< HEAD - Slot(long _seqnum, long _machineid) { - this(_seqnum, _machineid, new byte[ HMAC_SIZE], null); -======= + Slot(Table _table, long _seqnum, long _machineid) { this(_table, _seqnum, _machineid, new byte[HMAC_SIZE], null); ->>>>>>> f80cc30f294899f47cef3507334f8ca357862e5e } byte[] getHMAC() { diff --git a/src/js/iotjs/.jshintrc b/src/js/iotjs/.jshintrc index 0959e67..63937d2 100644 --- a/src/js/iotjs/.jshintrc +++ b/src/js/iotjs/.jshintrc @@ -2,7 +2,6 @@ "node": true, "esnext": true, "bitwise": true, - "camelcase": true, "curly": true, "eqeqeq": true, "immed": true, @@ -10,7 +9,6 @@ "latedef": true, "newcap": true, "noarg": true, - "quotmark": "single", "regexp": true, "undef": true, "unused": true, diff --git a/src/js/iotjs/orig/compat.txt b/src/js/iotjs/orig/compat.txt new file mode 100644 index 0000000..af5aedf --- /dev/null +++ b/src/js/iotjs/orig/compat.txt @@ -0,0 +1,3 @@ +1.Byte[] -> Uint8Array +2.Static decode method in slot.js takes the table, uint8array and the secret key as the argument +3.Vector = array of entries [] \ No newline at end of file diff --git a/src/js/iotjs/orig/slot.js b/src/js/iotjs/orig/slot.js index 35ca266..6af5a18 100644 --- a/src/js/iotjs/orig/slot.js +++ b/src/js/iotjs/orig/slot.js @@ -1,16 +1,33 @@ class Slot { - constructor(seqnum, machineid, prevhmac, hmac) { + constructor(table, seqnum, machineid, prevhmac, hmac) { this.SLOT_SIZE = 2048; this.RESERVED_SPACE = 64; this.HMAC_SIZE = 32; - (typeof seqnum === "number") ? this.seqnum = seqnum: throw new Error("seqnum should be a number"); - (typeof machineid === "number") ? this.machineid = seqnum: throw new Error("machine should be a number"); + if(typeof seqnum === "number"){ + this.seqnum = seqnum; + }else{ + throw new Error("seqnum should be a number"); + } + if(typeof machineid === "number"){ + this.machineid = machineid; + }else{ + throw new Error("machine should be a number"); + } this.livecount = 1; this.seqnumlive = true; - (prevhmac && prevhmac instanceof Uint8Array) ? this.prevhmac = prevhmac: this.prevhmac = new Uint8Array(this.HMAC_SIZE)); - (hmac && hmac instanceof Uint8Array) ? this.hmac = hmac: this.hmac = null; + if(prevhmac && prevhmac instanceof Uint8Array){ + this.prevhmac = prevhmac; + }else{ + throw new Error("prevhmac input not valid"); + } + if(hmac && hmac instanceof Uint8Array){ + this.hmac = hmac + }else{ + throw new Error("Hmac input not valid"); + } this.entries = []; - this.freespace = this.SLOT_SIZE - getBaseSize(); //??????? + this.freespace = this.SLOT_SIZE - getBaseSize(); //??????? + this.table = table; } getHMAC() { return this.hmac; @@ -23,30 +40,132 @@ class Slot { var obj; this.entries.push(_.extend(obj, entry)); this.livecount++; - freespace -= entry.getSize(); + this.freespace -= entry.getSize(); } } addShallowEntry(entry){ if(entry && entry instanceof Entry){ this.entries.push(entry); this.livecount++; - freespace -= entry.getSize(); + this.freespace -= entry.getSize(); } } hasSpace(entry){ var newfreespace = this.freespace - entry.getSize(); return newfreespace > this.RESERVED_SPACE; } - canFit(entry){ - var newfreespace = this.freespace - entry.getSize(); - return newfreespace >= 0; - } getEntries(){ return this.entries; } - static decode(array){ + static decode(table, array, key){ var cond1 = (array && array instanceof Uint8Array); if(cond1){ + var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator='']),key); + + var realmac = new Uint8Array(mac.length); + for(var i=0; i< mac.length ; i++){ + realmac[i] = mac.charCodeAt(i); + } + + var bb = new ByteBuffer().wrap(array.join([separator=''])).flip(); + var hmac= new Uint8Array(this.HMAC_SIZE); + var prevhmac = new Uint8Array(this.HMAC_SIZE); + for(var i = 0; i entry.encode(bb)); + + var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator='']),key); + var realmac = new Uint8Array(mac.length); + for(var i=0; i< mac.length ; i++){ + realmac[i] = mac.charCodeAt(i); + } + this.hmac = realmac; + bb.reset(); + bb.wrap(realmac.join([separator=''])); + return new Uint8Array(bb.toArrayBuffer()); + } + /** + * Returns the empty size of a Slot. Includes 2 HMACs, the machine + * identifier, the sequence number, and the number of entries. + */ + getBaseSize(){ + return 2*this.HMAC_SIZE+2*8+2*4; //Problematic area + } + + getLiveEntries(resize){ + var liveEntries = []; + this.entries.forEach(function(entry){ + if(entry.isLive === true){ + if(!resize || entry.getType() !== entry.TypeTableStatus){ + liveEntries.push(entry); + } + }; + }); + + if(this.seqnumlive && !resize){ + liveEntries.push(new LastMessage(this,this.machineid,this.seqnumlive)) } + + return liveEntries; + } + + getSequenceNumber() { + return this.seqnum; + } + + getMachineID() { + return this.machineid; + } + + setDead() { + this.seqnumlive=false; + this.decrementLiveCount(); + } + + decrementLiveCount() { + this.livecount--; + if (this.livecount === 0) + this.table.decrementLiveCount(); + } + + isLive() { + return this.livecount > 0; + } + + toString() { + return '<'+this.getSequenceNumber()+'>'; } -} \ No newline at end of file + +} + \ No newline at end of file diff --git a/src/js/iotjs/src/main.js b/src/js/iotjs/src/main.js index b4485fd..f8f03e7 100644 --- a/src/js/iotjs/src/main.js +++ b/src/js/iotjs/src/main.js @@ -60,7 +60,7 @@ var forge = require('node-forge'); var decryptedData = JSON.parse(bytes.toString(crypto.enc.Utf8)); // console.log(decryptedData); - var e = crypto.HmacMD5("Mess", "Secret Passphrase"); + var e = crypto.HmacMD5("Message", "Secret Passphrase"); console.log(typeof e.toString()); } }()) \ No newline at end of file diff --git a/src/js/iotjs/src/slot.js b/src/js/iotjs/src/slot.js index e69de29..0a2824b 100644 --- a/src/js/iotjs/src/slot.js +++ b/src/js/iotjs/src/slot.js @@ -0,0 +1,208 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Slot = function () { + function Slot(table, seqnum, machineid, prevhmac, hmac) { + _classCallCheck(this, Slot); + + this.SLOT_SIZE = 2048; + this.RESERVED_SPACE = 64; + this.HMAC_SIZE = 32; + if (typeof seqnum === "number") { + this.seqnum = seqnum; + } else { + throw new Error("seqnum should be a number"); + } + if (typeof machineid === "number") { + this.machineid = machineid; + } else { + throw new Error("machine should be a number"); + } + this.livecount = 1; + this.seqnumlive = true; + if (prevhmac && prevhmac instanceof Uint8Array) { + this.prevhmac = prevhmac; + } else { + throw new Error("prevhmac input not valid"); + } + if (hmac && hmac instanceof Uint8Array) { + this.hmac = hmac; + } else { + throw new Error("Hmac input not valid"); + } + this.entries = []; + this.freespace = this.SLOT_SIZE - getBaseSize(); //??????? + this.table = table; + } + + _createClass(Slot, [{ + key: "getHMAC", + value: function getHMAC() { + return this.hmac; + } + }, { + key: "getPrevHmac", + value: function getPrevHmac() { + return this.prevhmac; + } + }, { + key: "addEntry", + value: function addEntry(entry) { + if (entry && entry instanceof Entry) { + var obj; + this.entries.push(_.extend(obj, entry)); + this.livecount++; + this.freespace -= entry.getSize(); + } + } + }, { + key: "addShallowEntry", + value: function addShallowEntry(entry) { + if (entry && entry instanceof Entry) { + this.entries.push(entry); + this.livecount++; + this.freespace -= entry.getSize(); + } + } + }, { + key: "hasSpace", + value: function hasSpace(entry) { + var newfreespace = this.freespace - entry.getSize(); + return newfreespace > this.RESERVED_SPACE; + } + }, { + key: "getEntries", + value: function getEntries() { + return this.entries; + } + }, { + key: "encode", + value: function encode(key) { + var array = new Uint8Array(this.SLOT_SIZE); + var bb = new ByteBuffer().wrap(array.join([separator = ''])); + //leave space for slot HMAC + bb.skip(this.HMAC_SIZE); + bb.writeIString(this.prevhmac.join([separator = ''])); + bb.writeInt64(this.seqnum); + bb.writeInt64(this.machineid); + bb.writeByte(this.entries.length); + this.entries.forEach(function (entry) { + return entry.encode(bb); + }); + + var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator = '']), key); + var realmac = new Uint8Array(mac.length); + for (var i = 0; i < mac.length; i++) { + realmac[i] = mac.charCodeAt(i); + } + this.hmac = realmac; + bb.reset(); + bb.wrap(realmac.join([separator = ''])); + return new Uint8Array(bb.toArrayBuffer()); + } + /** + * Returns the empty size of a Slot. Includes 2 HMACs, the machine + * identifier, the sequence number, and the number of entries. + */ + + }, { + key: "getBaseSize", + value: function getBaseSize() { + return 2 * this.HMAC_SIZE + 2 * 8 + 2 * 4; //Problematic area + } + }, { + key: "getLiveEntries", + value: function getLiveEntries(resize) { + var liveEntries = []; + this.entries.forEach(function (entry) { + if (entry.isLive === true) { + if (!resize || entry.getType() !== entry.TypeTableStatus) { + liveEntries.push(entry); + } + } + }); + + if (this.seqnumlive && !resize) { + liveEntries.push(new LastMessage(this, this.machineid, this.seqnumlive)); + } + + return liveEntries; + } + }, { + key: "getSequenceNumber", + value: function getSequenceNumber() { + return this.seqnum; + } + }, { + key: "getMachineID", + value: function getMachineID() { + return this.machineid; + } + }, { + key: "setDead", + value: function setDead() { + this.seqnumlive = false; + this.decrementLiveCount(); + } + }, { + key: "decrementLiveCount", + value: function decrementLiveCount() { + this.livecount--; + if (this.livecount === 0) this.table.decrementLiveCount(); + } + }, { + key: "isLive", + value: function isLive() { + return this.livecount > 0; + } + }, { + key: "toString", + value: function toString() { + return '<' + this.getSequenceNumber() + '>'; + } + }], [{ + key: "decode", + value: function decode(table, array, key) { + var cond1 = array && array instanceof Uint8Array; + if (cond1) { + var mac = crypto.HmacMD5(array.slice(this.HMAC_SIZE).join([separator = '']), key); + + var realmac = new Uint8Array(mac.length); + for (var i = 0; i < mac.length; i++) { + realmac[i] = mac.charCodeAt(i); + } + + var bb = new ByteBuffer().wrap(array.join([separator = ''])).flip(); + var hmac = new Uint8Array(this.HMAC_SIZE); + var prevhmac = new Uint8Array(this.HMAC_SIZE); + for (var i = 0; i < this.HMAC_SIZE; i++) { + hmac[i] = bb.readByte(); + } + for (var j = 0; j < this.HMAC_SIZE; j++) { + prevhmac[j] = bb.readByte(); + } + //shallow compare + for (var k = 0; k < this.HMAC_SIZE; k++) { + if ((hmac[k] !== realmac[k])) { + throw new Error("Server Error: Invalid HMAC! Potential Attack!"); + } + } + var _seqnum = bb.readLong(); + var _machineid = bb.readLong(); + var numentries = bb.readInt8(); + + var _slot = new Slot(table, _seqnum, _machineid, prevhmac, hmac); + + for (var l = 0; l < numentries; l++) { + _slot.addShallowEntry(Entry.decode(_slot, bb)); + } + return _slot; + } + } + }]); + + return Slot; +}(); \ No newline at end of file -- 2.34.1 From 5db510e66534658d0e113677aec7eb3bf913b940 Mon Sep 17 00:00:00 2001 From: joelbandi Date: Mon, 1 Aug 2016 05:44:14 -0700 Subject: [PATCH 11/16] minor fix --- src/js/iotjs/src/slot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/iotjs/src/slot.js b/src/js/iotjs/src/slot.js index 0a2824b..c283546 100644 --- a/src/js/iotjs/src/slot.js +++ b/src/js/iotjs/src/slot.js @@ -26,12 +26,12 @@ var Slot = function () { if (prevhmac && prevhmac instanceof Uint8Array) { this.prevhmac = prevhmac; } else { - throw new Error("prevhmac input not valid"); + this.prevhmac = new Uint8Array(this.HMAC_SIZE); } if (hmac && hmac instanceof Uint8Array) { this.hmac = hmac; } else { - throw new Error("Hmac input not valid"); + this.hmac = null; } this.entries = []; this.freespace = this.SLOT_SIZE - getBaseSize(); //??????? -- 2.34.1 From 6ce410e7a90dbe8531857748499c9ea14a2bd97d Mon Sep 17 00:00:00 2001 From: rtrimana Date: Mon, 1 Aug 2016 09:04:16 -0700 Subject: [PATCH 12/16] Merging changes --- doc/iotcloud.tex | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/iotcloud.tex b/doc/iotcloud.tex index ad8f80a..c2b7de8 100644 --- a/doc/iotcloud.tex +++ b/doc/iotcloud.tex @@ -537,13 +537,13 @@ $\tuple{ck,\tuple{k, v}} \in KV_s \wedge \forall \tuple{ck_s,\tuple{k_s, v_s}} \in KV_s, k = k_s$ \\ \begin{algorithmic}[1] -\Function{PutKVPair}{$KV_s,\tuple{k_s,v_s}$} -\State $\tuple{ck_s,\tuple{k_s,v_t}} \gets GetKV(KV_s,k_s)$ +\Function{PutKVPair}{$\tuple{k_s,v_s}$} +\State $\tuple{ck_s,\tuple{k_s,v_t}} \gets GetKV(KV,k_s)$ \If{$\tuple{ck_s,\tuple{k_s,v_t}} = \emptyset$} - \State $KV_s \gets KV_s \cup \{\tuple{ck_p, \tuple{k_s,v_s}}\}$ + \State $KV \gets KV \cup \{\tuple{ck_p, \tuple{k_s,v_s}}\}$ \State $ck_p \gets ck_p + 1$ \Else - \State $KV_s \gets (KV_s - \{\tuple{ck_s, \tuple{k_s,v_t}}\}) \cup + \State $KV \gets (KV - \{\tuple{ck_s, \tuple{k_s,v_t}}\}) \cup \{\tuple{ck_s, \tuple{k_s,v_s}}\}$ \EndIf \State \Return{$KV_s$} @@ -596,19 +596,22 @@ $\tuple{ck,\tuple{k, v}} \in KV_s \wedge \end{algorithmic} \begin{algorithmic}[1] -\Function{ReinsertLastSlot}{$need_s,sl_{s_{last}},max'_s$} -\If{$need_s$} - \State $s_s \gets GetLastS(sl_{s_{last}})$ - \State $sv_s \gets GetSV(sl_{s_{last}})$ - \State $\tuple{stat_s,SL_s} \gets \Call{PutSlot}{s_s,sv_s,max'_s}$ - \State $cr_s \gets \Call{HandleCollision}{\tuple{stat_s,SL_s}}$ -\EndIf -\State \Return{$cr_s$} +\Function{ReinsertLastSlot}{$MS_s,SK_s,sl_{s_{last}},max'_s,hmac_{p_s}$} +\State $s_s \gets MaxLastSeqN(MS_s)$ +\State $sv_s \gets GetSV(sl_{s_{last}})$ +\State $Dat_s \gets Decrypt(SK,sv_s)$ +\State $DE_s \gets GetDatEnt(Dat_s)$ +\State $hmac_{c_s} \gets Hmac(DE_s,SK_s)$ +\State $Dat_s \gets CreateDat(s_s,id_{self},hmac_{p_s},DE_p,hmac_{c_s})$ +\State $hmac_{p_s} \gets hmac_{c_s}$ +\State $\tuple{stat_s,SL_s} \gets \Call{PutSlot}{s_s,sv_s,max'_s}$ +\State $cr_s \gets \Call{HandleCollision}{\tuple{stat_s,SL_s}}$ +\State \Return{$\tuple{cr_s,hmac_{p_p}}$} \EndFunction \end{algorithmic} \note{Shouldn't this function do something pretty sophisticated about seeing what data we actually need to keep from the last slot and not just insert the entire thing?} -\note{Probably best to just not call this function is $need_s$ is false and not pass in such parameters. It makes it harder to read.} +\note{Probably best to just not call this function if $need_s$ is false and not pass in such parameters. It makes it harder to read.} \begin{algorithmic}[1] @@ -664,7 +667,10 @@ $\tuple{ck,\tuple{k, v}} \in KV_s \wedge \State $sv_p \gets Encrypt(Dat_p,SK)$ \State $\tuple{stat_p,SL_p} \gets \Call{PutSlot}{s_p,sv_p,max'_p}$ \State $cr_p \gets \Call{HandleCollision}{\tuple{stat_p,SL_p}}$ -\State $cr_{p_{last}} \gets \Call{ReinsertLastSlot}{need_p,sl_{last},max'_p}$ +\If{$need_p$} + \State $\tuple{cr_{p_{last}},hmac_{p_p}} \gets + \Call{ReinsertLastSlot}{MS,SK,sl_{last},max'_p,hmac_{p_p}}$ +\EndIf \EndProcedure \end{algorithmic} -- 2.34.1 From 5f55bf39b74645a2ac989751e1e372208c982a08 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Mon, 1 Aug 2016 10:30:15 -0700 Subject: [PATCH 13/16] forget rejected message list --- src/java/iotcloud/Table.java | 44 +++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index 3afb1a9..cf7095e 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -18,6 +18,7 @@ final public class Table { private HashMap table=new HashMap(); private HashMap > lastmessagetable=new HashMap >(); private HashMap > watchlist = new HashMap >(); + private Vector rejectedmessagelist=new Vector(); private SlotBuffer buffer; private CloudComm cloud; private long sequencenumber; @@ -29,6 +30,7 @@ final public class Table { private int chance; static final double RESIZE_MULTIPLE = 1.2; static final double RESIZE_THRESHOLD = 0.75; + static final int REJECTED_THRESHOLD = 5; private int resizethreshold; private long lastliveslotseqn; private Random random=new Random(); @@ -125,6 +127,37 @@ final public class Table { s.addEntry(status); } + if (!rejectedmessagelist.isEmpty()) { + long old_seqn=rejectedmessagelist.firstElement(); + if (rejectedmessagelist.size() > REJECTED_THRESHOLD) { + long new_seqn=rejectedmessagelist.lastElement(); + RejectedMessage rm=new RejectedMessage(s, localmachineid, old_seqn, new_seqn, false); + s.addEntry(rm); + } else { + long prev_seqn=old_seqn; + for(int i=0; i Date: Mon, 1 Aug 2016 12:51:17 -0700 Subject: [PATCH 14/16] simplify code --- src/java/iotcloud/Table.java | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index cf7095e..bbcfe6a 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -134,27 +134,29 @@ final public class Table { RejectedMessage rm=new RejectedMessage(s, localmachineid, old_seqn, new_seqn, false); s.addEntry(rm); } else { - long prev_seqn=old_seqn; - for(int i=0; i Date: Mon, 1 Aug 2016 12:56:38 -0700 Subject: [PATCH 15/16] add todo item --- src/java/iotcloud/Table.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index bbcfe6a..7c798ad 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -128,6 +128,10 @@ final public class Table { } if (!rejectedmessagelist.isEmpty()) { + /* TODO: We should avoid generating a rejected message entry if + * there is already a sufficient entry in the queue (e.g., + * equalsto value of true and same sequence number). */ + long old_seqn=rejectedmessagelist.firstElement(); if (rejectedmessagelist.size() > REJECTED_THRESHOLD) { long new_seqn=rejectedmessagelist.lastElement(); -- 2.34.1 From 15925e4e1a94fd66990254b21bc0bf2224b90d2b Mon Sep 17 00:00:00 2001 From: rtrimana Date: Mon, 1 Aug 2016 13:55:27 -0700 Subject: [PATCH 16/16] Adding/fixing FastCGI required modules names --- src/server/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/README.txt b/src/server/README.txt index 7de6bf9..6eb138f 100644 --- a/src/server/README.txt +++ b/src/server/README.txt @@ -1,5 +1,5 @@ 1) Requires apache2 -2) Requires fastcgi (libapache2-mod-fastcfi) +2) Requires fastcgi (libapache2-mod-fastcgi and libfcgi-dev) Setup on ubuntu 1) Install modules -- 2.34.1