|
@@ -36,21 +36,7 @@ bool FileMan::isListingExtended() { return islisting && extendedListing; }
|
|
|
|
|
|
bool FileMan::isEncrypted() { return keyenabled; }
|
|
|
|
|
|
-vector<vector<char>> FileMan::chunkify(char *data, unsigned int size) {
|
|
|
- vector<vector<char>> ret;
|
|
|
- vector<char> chunk;
|
|
|
- unsigned int i;
|
|
|
- for (i = 0; (i + max_read_len) < size; i += max_read_len) {
|
|
|
- chunk = vector<char>(data + i, data + i + max_read_len);
|
|
|
- ret.push_back(chunk);
|
|
|
- }
|
|
|
- chunk = vector<char>(data + i, data + size);
|
|
|
- ret.push_back(chunk);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
bool FileMan::openPut(const string &path) {
|
|
|
- std::ifstream putfile;
|
|
|
std::fstream keyfile;
|
|
|
putpath = path;
|
|
|
putname = pathToFilename(path);
|
|
@@ -68,32 +54,71 @@ bool FileMan::openPut(const string &path) {
|
|
|
}
|
|
|
putfile.seekg(0);
|
|
|
|
|
|
- // read into memory and chunkify
|
|
|
+ // if crypto enabled, encrypt now
|
|
|
+ if (keyenabled) {
|
|
|
+ cipherpath = path + ".tmp";
|
|
|
+
|
|
|
+ if (!!std::ifstream(cipherpath)) {
|
|
|
+ // close put if tmp file already exists
|
|
|
+ closePut();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- char *temp = new char[size + sizeof(signature)];
|
|
|
- memcpy(temp, signature, sizeof(signature));
|
|
|
- putfile.read(temp + sizeof(signature), size);
|
|
|
+ std::ofstream cipherFile(cipherpath, std::ios::binary);
|
|
|
+ if (!cipherFile) {
|
|
|
+ closePut();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- size += sizeof(signature);
|
|
|
+ // resize buffer to also fit IV and tag
|
|
|
+ size_t additionalsize = sizeof(iv) + sizeof(tag);
|
|
|
+
|
|
|
+ // skip first 32 bytes. Those are needed for the header
|
|
|
+ cipherFile.seekp(additionalsize);
|
|
|
|
|
|
- // have all file in memory prepended with signature
|
|
|
- // if crypto enabled, encrypt now
|
|
|
- if (keyenabled) {
|
|
|
if (!initCryptoE()) {
|
|
|
// failed to init crypto, do not continue
|
|
|
- delete[] temp;
|
|
|
return false;
|
|
|
}
|
|
|
- // resize buffer to also fit IV and tag
|
|
|
- size_t additionalsize = sizeof(iv) + sizeof(tag);
|
|
|
- unsigned char *cipher = new unsigned char[size];
|
|
|
+
|
|
|
+ unsigned char *plain = new unsigned char[max_read_len];
|
|
|
+ unsigned char *cipher = new unsigned char[max_read_len];
|
|
|
int cipherlen;
|
|
|
|
|
|
- if (!EVP_EncryptUpdate(cryptctxe, cipher, &cipherlen, (unsigned char *)temp, size)) {
|
|
|
+ // prepend signature
|
|
|
+ memcpy(plain, signature, sizeof(signature));
|
|
|
+
|
|
|
+ if (!EVP_EncryptUpdate(cryptctxe, cipher, &cipherlen, plain, sizeof(signature))) {
|
|
|
setOpensslError();
|
|
|
std::cerr << __PRETTY_FUNCTION__ << " failed to update " << getOpensslError() << std::endl;
|
|
|
}
|
|
|
- if (!EVP_EncryptFinal_ex(cryptctxe, cipher + cipherlen, &cipherlen)) {
|
|
|
+
|
|
|
+ cipherFile.write((char *)cipher, cipherlen);
|
|
|
+
|
|
|
+ while ((std::size_t)(putfile.tellg()) + max_read_len < size) {
|
|
|
+ putfile.read((char *)plain, max_read_len);
|
|
|
+
|
|
|
+ if (!EVP_EncryptUpdate(cryptctxe, cipher, &cipherlen, plain, max_read_len)) {
|
|
|
+ setOpensslError();
|
|
|
+ std::cerr << __PRETTY_FUNCTION__ << " failed to update " << getOpensslError() << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ cipherFile.write((char *)cipher, cipherlen);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (putfile.tellg() < size - 1) {
|
|
|
+ int rest = size - putfile.tellg();
|
|
|
+ putfile.read((char *)plain, rest);
|
|
|
+
|
|
|
+ if (!EVP_EncryptUpdate(cryptctxe, cipher, &cipherlen, plain, rest)) {
|
|
|
+ setOpensslError();
|
|
|
+ std::cerr << __PRETTY_FUNCTION__ << " failed to update " << getOpensslError() << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ cipherFile.write((char *)cipher, cipherlen);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!EVP_EncryptFinal_ex(cryptctxe, cipher, &cipherlen)) {
|
|
|
setOpensslError();
|
|
|
std::cerr << __PRETTY_FUNCTION__ << " failed to finalize " << getOpensslError() << std::endl;
|
|
|
}
|
|
@@ -103,29 +128,35 @@ bool FileMan::openPut(const string &path) {
|
|
|
std::cerr << __PRETTY_FUNCTION__ << " failed to get tag " << getOpensslError() << std::endl;
|
|
|
}
|
|
|
|
|
|
- delete[] temp;
|
|
|
- temp = new char[size + additionalsize];
|
|
|
-
|
|
|
// prepend IV and tag
|
|
|
- memcpy(temp, iv, sizeof(iv));
|
|
|
- memcpy(temp + sizeof(iv), tag, sizeof(tag));
|
|
|
- memcpy(temp + additionalsize, cipher, size);
|
|
|
+ cipherFile.seekp(0);
|
|
|
+ cipherFile.write((char *)iv, sizeof(iv));
|
|
|
+ cipherFile.write((char *)tag, sizeof(tag));
|
|
|
+
|
|
|
+ cipherFile.close();
|
|
|
+ putfile.close();
|
|
|
|
|
|
delete[] cipher;
|
|
|
+ delete[] plain;
|
|
|
+
|
|
|
+ // now open cipher file as put file
|
|
|
+ putfile.open(cipherpath, std::ios::ate | std::ios::binary);
|
|
|
+ if (putfile.is_open()) {
|
|
|
+ size = putfile.tellg();
|
|
|
+ putfile.seekg(0);
|
|
|
+ } else {
|
|
|
+ closePut();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- // increase size to also include IV and tag
|
|
|
- size += sizeof(iv) + sizeof(tag);
|
|
|
deinitCryptoE();
|
|
|
+ } else {
|
|
|
+ size += sizeof(signature);
|
|
|
}
|
|
|
|
|
|
- // chunkify
|
|
|
- putdata = chunkify(temp, size);
|
|
|
+ // calculate chunks
|
|
|
putsize = size;
|
|
|
- putchunksRemaining = putchunks = putdata.size();
|
|
|
-
|
|
|
- delete[] temp;
|
|
|
-
|
|
|
- // end read into memory and chunkify
|
|
|
+ putchunksRemaining = putchunks = size / max_read_len + (size % max_read_len > 0 ? 1 : 0);
|
|
|
|
|
|
isputting = true;
|
|
|
|
|
@@ -181,7 +212,7 @@ bool FileMan::openKey(const string &path) {
|
|
|
}
|
|
|
|
|
|
void FileMan::closePut() {
|
|
|
- putdata = vector<vector<char>>();
|
|
|
+ putfile.close();
|
|
|
putname = "";
|
|
|
putpath = "";
|
|
|
putchunks = 0;
|
|
@@ -189,6 +220,11 @@ void FileMan::closePut() {
|
|
|
isputting = false;
|
|
|
memset(iv, 0, sizeof(iv));
|
|
|
memset(tag, 0, sizeof(tag));
|
|
|
+
|
|
|
+ if (keyenabled && !!std::ifstream(cipherpath)) {
|
|
|
+ // delete tmp cipher file if it exists
|
|
|
+ std::remove(cipherpath.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void FileMan::closeGet() {
|
|
@@ -303,7 +339,23 @@ void FileMan::setListChunks(int chunks) {
|
|
|
}
|
|
|
|
|
|
vector<char> FileMan::readPut() {
|
|
|
- vector<char> data = putdata[putchunks - putchunksRemaining];
|
|
|
+ int chunk = putchunks - putchunksRemaining;
|
|
|
+ vector<char> data;
|
|
|
+
|
|
|
+ int toread = max_read_len;
|
|
|
+ if (putchunksRemaining == 1) {
|
|
|
+ toread = putsize - (putchunks - 1) * max_read_len;
|
|
|
+ }
|
|
|
+
|
|
|
+ data.resize(toread);
|
|
|
+
|
|
|
+ if (chunk == 0 && !keyenabled) {
|
|
|
+ memcpy(&data.front(), signature, sizeof(signature));
|
|
|
+ putfile.read(&data.front() + sizeof(signature), toread - sizeof(signature));
|
|
|
+ } else {
|
|
|
+ putfile.read(&data.front(), toread);
|
|
|
+ }
|
|
|
+
|
|
|
putchunksRemaining--;
|
|
|
return data;
|
|
|
}
|
|
@@ -362,7 +414,7 @@ void FileMan::setOpensslError() {
|
|
|
bool FileMan::initCryptoE() {
|
|
|
// try to initialize crypto context
|
|
|
if (!cryptoreadye) {
|
|
|
- std::cerr << __PRETTY_FUNCTION__ << " init crypto" << std::endl;
|
|
|
+ //~ std::cerr << __PRETTY_FUNCTION__ << " init crypto" << std::endl;
|
|
|
if (!(cryptctxe = EVP_CIPHER_CTX_new())) {
|
|
|
setOpensslError();
|
|
|
return false;
|
|
@@ -379,7 +431,7 @@ bool FileMan::initCryptoE() {
|
|
|
bool FileMan::initCryptoD() {
|
|
|
// try to initialize crypto context
|
|
|
if (!cryptoreadyd) {
|
|
|
- std::cerr << __PRETTY_FUNCTION__ << " init crypto" << std::endl;
|
|
|
+ //~ std::cerr << __PRETTY_FUNCTION__ << " init crypto" << std::endl;
|
|
|
if (!(cryptctxd = EVP_CIPHER_CTX_new())) {
|
|
|
setOpensslError();
|
|
|
return false;
|
|
@@ -437,15 +489,15 @@ void FileMan::writeEnc(const vector<char> data) {
|
|
|
setOpensslError();
|
|
|
std::cerr << __PRETTY_FUNCTION__ << " failed to update " << getOpensslError() << std::endl;
|
|
|
}
|
|
|
- std::cerr << __PRETTY_FUNCTION__ << " decrypted" << std::endl;
|
|
|
+ //~ std::cerr << __PRETTY_FUNCTION__ << " decrypted" << std::endl;
|
|
|
if (!EVP_CIPHER_CTX_ctrl(cryptctxd, EVP_CTRL_GCM_SET_TAG, 16, tag)) {
|
|
|
setOpensslError();
|
|
|
std::cerr << __PRETTY_FUNCTION__ << " failed to finalize " << getOpensslError() << std::endl;
|
|
|
}
|
|
|
- std::cerr << __PRETTY_FUNCTION__ << " set tag" << std::endl;
|
|
|
+ //~ std::cerr << __PRETTY_FUNCTION__ << " set tag" << std::endl;
|
|
|
if (0 < EVP_DecryptFinal_ex(cryptctxd, plain + plainlen, &finallen)) {
|
|
|
plainlen += finallen;
|
|
|
- std::cerr << __PRETTY_FUNCTION__ << " finalized with len " << plainlen << std::endl;
|
|
|
+ //~ std::cerr << __PRETTY_FUNCTION__ << " finalized with len " << plainlen << std::endl;
|
|
|
getfile.close();
|
|
|
// check signature
|
|
|
if (memcmp(plain, signature, 4)) {
|