* 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:
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() {
"node": true,
"esnext": true,
"bitwise": true,
- "camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
- "quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
--- /dev/null
+1.Byte[] -> Uint8Array
+2.Static decode method in slot.js takes the table, uint8array and the secret key as the argument
+3.Vector<Entries> = array of entries []
\ No newline at end of file
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;
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<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;
+ }
+ }
+ 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((entry) => 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
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
+"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