From ea13af1b791836a1b5e5c1d382dd2d02e180430d Mon Sep 17 00:00:00 2001 From: bdemsky Date: Thu, 1 Mar 2018 11:06:18 -0800 Subject: [PATCH] edits --- version2/src/C/CloudComm.cc | 166 +++++++++++++++------------------- version2/src/C/CloudComm.h | 17 ++-- version2/src/C/Crypto.cc | 1 + version2/src/C/Crypto.h | 12 +++ version2/src/C/Error.h | 1 + version2/src/C/Mac.h | 2 +- version2/src/C/SecureRandom.h | 1 + version2/src/C/common.h | 6 +- 8 files changed, 102 insertions(+), 104 deletions(-) create mode 100644 version2/src/C/Crypto.cc create mode 100644 version2/src/C/Crypto.h diff --git a/version2/src/C/CloudComm.cc b/version2/src/C/CloudComm.cc index c6c0e75..06d6a89 100644 --- a/version2/src/C/CloudComm.cc +++ b/version2/src/C/CloudComm.cc @@ -5,6 +5,9 @@ #include "Error.h" #include "URL.h" #include "Mac.h" +#include "Table.h" +#include "Crypto.h" +#include "ByteBuffer.h" /** * Empty Constructor needed for child class. @@ -24,6 +27,12 @@ CloudComm::CloudComm() : { } +void * threadWrapper(void * cloud) { + CloudComm *c = (CloudComm *) cloud; + c->localServerWorkerFunction(); + return NULL; +} + /** * Constructor for actual use. Takes in the url and password. */ @@ -40,26 +49,20 @@ CloudComm::CloudComm(Table *_table, IoTString *_baseurl, IoTString *_password, doEnd(false), timer(TimingSingleton_getInstance()) { if (listeningPort > 0) { - localServerThread = new Thread(new Runnable() { - void run() { - localServerWorkerFunction(); - } - }); - localServerThread->start(); + pthread_create(&localServerThread, NULL, threadWrapper, this); } } /** * Generates Key from password. */ -SecretKeySpec *CloudComm::initKey() { +AESKey *CloudComm::initKey() { try { - PBEKeySpec *keyspec = new PBEKeySpec(password->internalBytes(), - salt, - 65536, - 128); - SecretKey *tmpkey = SecretKeyFactory_getInstance("PBKDF2WithHmacSHA256")->generateSecret(keyspec); - return new SecretKeySpec(tmpkey->getEncoded(), "AES"); + AESKey * key = new AESKey(password->internalBytes(), + salt, + 65536, + 128); + return key; } catch (Exception *e) { throw new Error("Failed generating key."); } @@ -99,7 +102,7 @@ void CloudComm::initCrypt() { /* * Builds the URL for the given request. */ -URL *CloudComm::buildRequest(bool isput, int64_t sequencenumber, int64_t maxentries) { +IoTString *CloudComm::buildRequest(bool isput, int64_t sequencenumber, int64_t maxentries) { const char *reqstring = isput ? "req=putslot" : "req=getslot"; char *buffer = (char *) malloc(baseurl->length() + 200); memcpy(buffer, baseurl->internalBytes(), baseurl->length()); @@ -108,8 +111,25 @@ URL *CloudComm::buildRequest(bool isput, int64_t sequencenumber, int64_t maxentr if (maxentries != 0) sprintf(&buffer[offset], "&max=%" PRId64, maxentries); IoTString *urlstr = new IoTString(buffer); - free(buffer); - return new URL(urlstr); + return urlstr; +} + +int openURL(IoTString *url, bool isPost) { + return 0; +} + +void writeURLData(int fd, Array *data) { +} + +void readURLData(int fd, Array * output) { +} + +int readURLInt(int fd) { + return 0; +} + +int getResponseCode(int fd) { + return 0; } void CloudComm::setSalt() { @@ -118,6 +138,7 @@ void CloudComm::setSalt() { return; } + int fd = -1; try { Array *saltTmp = new Array(CloudComm_SALT_SIZE); random->nextBytes(saltTmp); @@ -129,22 +150,11 @@ void CloudComm::setSalt() { IoTString *urlstr = new IoTString(buffer); free(buffer); - URL *url = new URL(urlstr); timer->startTime(); - URLConnection *con = url->openConnection(); - HttpURLConnection *http = (HttpURLConnection *) con; + fd = openURL(urlstr, true); + writeURLData(fd, saltTmp); - http->setRequestMethod("POST"); - http->setFixedLengthStreamingMode(saltTmp->length()); - http->setDoOutput(true); - http->setConnectTimeout(CloudComm_TIMEOUT_MILLIS); - http->connect(); - - OutputStream *os = http->getOutputStream(); - os->write(saltTmp); - os->flush(); - - int responsecode = http->getResponseCode(); + int responsecode = getResponseCode(fd); if (responsecode != HttpURLConnection_HTTP_OK) { throw new Error("Invalid response"); } @@ -158,30 +168,22 @@ void CloudComm::setSalt() { } bool CloudComm::getSalt() { - URL *url = NULL; - URLConnection *con = NULL; - HttpURLConnection *http = NULL; - + int fd = -1; + IoTString *urlstr = NULL; + try { char *buffer = (char *) malloc(baseurl->length() + 100); memcpy(buffer, baseurl->internalBytes(), baseurl->length()); int offset = baseurl->length(); offset += sprintf(&buffer[offset], "?req=getsalt"); - IoTString *urlstr = new IoTString(buffer); + urlstr = new IoTString(buffer); free(buffer); - - url = new URL(urlstr); } catch (Exception *e) { throw new Error("getSlot failed"); } try { timer->startTime(); - con = url->openConnection(); - http = (HttpURLConnection *) con; - http->setRequestMethod("POST"); - http->setConnectTimeout(CloudComm_TIMEOUT_MILLIS); - http->setReadTimeout(CloudComm_TIMEOUT_MILLIS); - http->connect(); + fd = openURL(urlstr, true); timer->endTime(); } catch (SocketTimeoutException *e) { timer->endTime(); @@ -192,16 +194,14 @@ bool CloudComm::getSalt() { try { timer->startTime(); - int responsecode = http->getResponseCode(); + int responsecode = getResponseCode(fd); if (responsecode != HttpURLConnection_HTTP_OK) { throw new Error("Invalid response"); } - InputStream *is = http->getInputStream(); if (is->available() > 0) { - DataInputStream *dis = new DataInputStream(is); - int salt_length = dis->readInt(); + int salt_length = readURLInt(fd); Array *tmp = new Array(salt_length); - dis->readFully(tmp); + readURLData(fd, tmp); salt = tmp; timer->endTime(); return true; @@ -246,7 +246,7 @@ Array *CloudComm::stripIVAndDecryptSlot(Array *rawData) { Array *ivBytes = new Array(CloudComm_IV_SIZE); Array *encryptedBytes = new Array(rawData->length() - CloudComm_IV_SIZE); System_arraycopy(rawData, 0, ivBytes, 0, CloudComm_IV_SIZE); - System_arraycopy(rawData, CloudComm_IV_SIZE, encryptedBytes, 0, encryptedBytes->length); + System_arraycopy(rawData, CloudComm_IV_SIZE, encryptedBytes, 0, encryptedBytes->length()); IvParameterSpec *ivSpec = new IvParameterSpec(ivBytes); Cipher *cipher = Cipher_getInstance("AES/CTR/NoPadding"); cipher->init(Cipher_DECRYPT_MODE, key, ivSpec); @@ -262,6 +262,7 @@ Array *CloudComm::stripIVAndDecryptSlot(Array *rawData) { * numbers. */ Array *CloudComm::putSlot(Slot *slot, int max) { + int fd = -1; try { if (salt == NULL) { if (!getSalt()) { @@ -273,19 +274,10 @@ Array *CloudComm::putSlot(Slot *slot, int max) { int64_t sequencenumber = slot->getSequenceNumber(); Array *slotBytes = slot->encode(mac); Array *chars = encryptSlotAndPrependIV(slotBytes, slot->getSlotCryptIV()); - URL *url = buildRequest(true, sequencenumber, max); + IoTString *url = buildRequest(true, sequencenumber, max); timer->startTime(); - URLConnection *con = url->openConnection(); - HttpURLConnection *http = (HttpURLConnection *) con; - http->setRequestMethod("POST"); - http->setFixedLengthStreamingMode(chars->length); - http->setDoOutput(true); - http->setConnectTimeout(CloudComm_TIMEOUT_MILLIS); - http->setReadTimeout(CloudComm_TIMEOUT_MILLIS); - http->connect(); - OutputStream *os = http->getOutputStream(); - os->write(chars); - os->flush(); + fd = openURL(url, true); + writeURLData(fd, chars); timer->endTime(); } catch (ServerException *e) { timer->endTime(); @@ -299,15 +291,13 @@ Array *CloudComm::putSlot(Slot *slot, int max) { try { timer->startTime(); - InputStream *is = http->getInputStream(); - DataInputStream *dis = new DataInputStream(is); Array *resptype = new Array(7); - dis->readFully(resptype); + readURLData(fd, resptype); timer->endTime(); - if (Arrays->equals(resptype, "getslot"->getBytes())) { - return processSlots(dis); - } else if (Arrays->equals(resptype, "putslot"->getBytes())) { + if (resptype->equals("getslot"->getBytes())) { + return processSlots(fd); + } else if (resptype->equals("putslot"->getBytes())) { return NULL; } else throw new Error("Bad response to putslot"); @@ -332,7 +322,7 @@ Array *CloudComm::getSlots(int64_t sequencenumber) { initCrypt(); } - URL *url = buildRequest(false, sequencenumber, 0); + IoTString *url = buildRequest(false, sequencenumber, 0); timer->startTime(); URLConnection *con = url->openConnection(); HttpURLConnection *http = (HttpURLConnection *) con; @@ -354,10 +344,8 @@ Array *CloudComm::getSlots(int64_t sequencenumber) { try { timer->startTime(); - InputStream *is = http->getInputStream(); - DataInputStream *dis = new DataInputStream(is); Array *resptype = new Array(7); - dis->readFully(resptype); + readURLData(fd, resptype); timer->endTime(); if (!resptype->equals("getslot"->getBytes())) throw new Error("Bad Response: " + new String(resptype)); @@ -375,29 +363,28 @@ Array *CloudComm::getSlots(int64_t sequencenumber) { * Method that actually handles building Slot objects from the * server response. Shared by both putSlot and getSlots. */ -Array *CloudComm::processSlots(DataInputStream *dis) { - int numberofslots = dis->readInt(); +Array *CloudComm::processSlots(int fd) { + int numberofslots = readURLInt(fd); Array *sizesofslots = new Array(numberofslots); Array *slots = new Array(numberofslots); for (int i = 0; i < numberofslots; i++) - sizesofslots->set(i, dis->readInt()); + sizesofslots->set(i, readURLInt(fd)); for (int i = 0; i < numberofslots; i++) { Array *rawData = new Array(sizesofslots->get(i)); - dis->readFully(rawData); + readURLData(rawData); Array *data = stripIVAndDecryptSlot(rawData); slots->set(i, Slot_decode(table, data, mac)); } - dis->close(); return slots; } -Array *sendLocalData(Array *sendData, int64_t localSequenceNumber, String host, int port) { +Array *CloudComm::sendLocalData(Array *sendData, int64_t localSequenceNumber, String host, int port) { if (salt == NULL) return NULL; try { printf("Passing Locally\n"); - mac->update(sendData); + mac->update(sendData, 0, sendData->length()); Array *genmac = mac->doFinal(); Array *totalData = new Array(sendData->length() + genmac->length()); System_arraycopy(sendData, 0, totalData, 0, sendData->length()); @@ -415,8 +402,8 @@ Array *sendLocalData(Array *sendData, int64_t localSequenceNumber, S timer->startTime(); // Send data to output (length of data, the data) - output->writeInt(encryptedData->length); - output->write(encryptedData, 0, encryptedData->length); + output->writeInt(encryptedData->length()); + output->write(encryptedData, 0, encryptedData->length()); output->flush(); int lengthOfReturnData = input->readInt(); @@ -427,16 +414,16 @@ Array *sendLocalData(Array *sendData, int64_t localSequenceNumber, S // We are done with this socket socket->close(); - mac->update(returnData, 0, returnData->length - HMAC_SIZE); + mac->update(returnData, 0, returnData->length() - CloudComm_HMAC_SIZE); Array *realmac = mac->doFinal(); - Array *recmac = new Array(HMAC_SIZE); - System_arraycopy(returnData, returnData->length - realmac->length, recmac, 0, realmac->length); + Array *recmac = new Array(CloudComm_HMAC_SIZE); + System_arraycopy(returnData, returnData->length() - realmac->length(), recmac, 0, realmac->length()); if (!recmac->equals(realmac)) throw new Error("Local Error: Invalid HMAC! Potential Attack!"); Array *returnData2 = new Array(lengthOfReturnData - recmac->length()); - System_arraycopy(returnData, 0, returnData2, 0, returnData2->length); + System_arraycopy(returnData, 0, returnData2, 0, returnData2->length()); return returnData2; } catch (Exception *e) { @@ -473,9 +460,9 @@ void CloudComm::localServerWorkerFunction() { // Decrypt the data readData = stripIVAndDecryptSlot(readData); - mac->update(readData, 0, readData->length - HMAC_SIZE); + mac->update(readData, 0, readData->length() - CloudComm_HMAC_SIZE); Array *genmac = mac->doFinal(); - Array *recmac = new Array(HMAC_SIZE); + Array *recmac = new Array(CloudComm_HMAC_SIZE); System_arraycopy(readData, readData->length() - recmac->length(), recmac, 0, recmac->length()); if (!recmac->equals(genmac)) @@ -486,7 +473,7 @@ void CloudComm::localServerWorkerFunction() { // Process the data Array *sendData = table->acceptDataFromLocal(returnData); - mac->update(sendData); + mac->update(sendData, 0, sendData->length()); Array *realmac = mac->doFinal(); Array *totalData = new Array(sendData->length() + realmac->length()); System_arraycopy(sendData, 0, totalData, 0, sendData->length()); @@ -521,10 +508,7 @@ void CloudComm::close() { doEnd = true; if (localServerThread != NULL) { - try { - localServerThread->join(); - } catch (Exception *e) { + if (pthread_join(localServerThread, NULL) != 0) throw new Error("Local Server thread join issue..."); - } } } diff --git a/version2/src/C/CloudComm.h b/version2/src/C/CloudComm.h index cdec495..2f82508 100644 --- a/version2/src/C/CloudComm.h +++ b/version2/src/C/CloudComm.h @@ -2,7 +2,7 @@ #define CLOUDCOMM_H #include "common.h" - +#include /** * This class provides a communication API to the webserver. It also * validates the HMACs on the slots and handles encryption. @@ -16,25 +16,27 @@ #define CloudComm_IV_SIZE 16 /** Sets the size for the HMAC. */ #define CloudComm_HMAC_SIZE 32 +#define HttpURLConnection_HTTP_OK 200 + class CloudComm { private: IoTString *baseurl; - SecretKeySpec *key; + AESKey *key; Mac *mac; IoTString *password; SecureRandom *random; Array *salt; Table *table; int32_t listeningPort; - Thread *localServerThread; + pthread_t localServerThread; bool doEnd; TimingSingleton *timer; /** * Generates Key from password. */ - SecretKeySpec *initKey(); + AESKey *initKey(); /** * Inits the HMAC generator. @@ -44,14 +46,14 @@ private: /* * Builds the URL for the given request. */ - URL *buildRequest(bool isput, int64_t sequencenumber, int64_t maxentries); + IoTString *buildRequest(bool isput, int64_t sequencenumber, int64_t maxentries); void setSalt(); bool getSalt(); Array *createIV(int64_t machineId, int64_t localSequenceNumber); Array *encryptSlotAndPrependIV(Array *rawData, Array *ivBytes); Array *stripIVAndDecryptSlot(Array *rawData); - Array *processSlots(DataInputStream dis); - void localServerWorkerFunction(); + Array *processSlots(int fd); + public: /** @@ -90,5 +92,6 @@ public: Array *sendLocalData(Array *sendData, int64_t localSequenceNumber, IoTString *host, int port); void close(); + void localServerWorkerFunction(); }; #endif diff --git a/version2/src/C/Crypto.cc b/version2/src/C/Crypto.cc new file mode 100644 index 0000000..3c66c90 --- /dev/null +++ b/version2/src/C/Crypto.cc @@ -0,0 +1 @@ +#include "Crypto.h" diff --git a/version2/src/C/Crypto.h b/version2/src/C/Crypto.h new file mode 100644 index 0000000..40a587f --- /dev/null +++ b/version2/src/C/Crypto.h @@ -0,0 +1,12 @@ +#ifndef CRYPTO_H +#define CRYPTO_H +#include "common.h" + +class AESKey { + public: + AESKey(Array * password, Array * salt, int iterationCount, int keyLength); + + private: +}; + +#endif diff --git a/version2/src/C/Error.h b/version2/src/C/Error.h index 1bb4dd0..61f1b6e 100644 --- a/version2/src/C/Error.h +++ b/version2/src/C/Error.h @@ -11,6 +11,7 @@ public: }; #define ServerException_TypeInputTimeout 1 +#define ServerException_TypeConnectTimeout 2 class ServerException { public: diff --git a/version2/src/C/Mac.h b/version2/src/C/Mac.h index 4c4d0f6..67543f0 100644 --- a/version2/src/C/Mac.h +++ b/version2/src/C/Mac.h @@ -6,7 +6,7 @@ class Mac { public: void update(Array *array, int32_t offset, int32_t len); Array *doFinal(); - void init(Key *key); + void init(AESKey *key); }; Mac *Mac_getInstance(const char *); diff --git a/version2/src/C/SecureRandom.h b/version2/src/C/SecureRandom.h index 34ccd72..111efa6 100644 --- a/version2/src/C/SecureRandom.h +++ b/version2/src/C/SecureRandom.h @@ -3,5 +3,6 @@ class SecureRandom { public: SecureRandom(); + void nextBytes(Array * array); }; #endif diff --git a/version2/src/C/common.h b/version2/src/C/common.h index a32c1d9..1b6a854 100644 --- a/version2/src/C/common.h +++ b/version2/src/C/common.h @@ -48,14 +48,10 @@ class Exception; class ServerException; //Code to write -class SecretKeySpec; -class PBEKeySpec; -class SecretKey; +class AESKey; class Mac; class SecureRandom; class Thread; -class DataInputStream; -class URL; class Random; class Key; #endif -- 2.34.1