password manager with aes encryption
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.3KB

  1. #ifndef _AES
  2. #define _AES
  3. #include <iostream>
  4. #include <stdio.h>
  5. #include <string>
  6. #include <sstream>
  7. #include <string.h>
  8. #include <algorithm>
  9. #include <typeinfo>
  10. #include <regex>
  11. #include <fstream>
  12. #include <openssl/evp.h>
  13. #include <openssl/pem.h>
  14. #include <openssl/aes.h>
  15. #include <openssl/err.h>
  16. #include <openssl/rand.h>
  17. #include <json/json.h>
  18. #include "lib/base64/base64.hpp"
  19. #define FAILURE -1
  20. #define SUCCESS 0
  21. #define AES_KEYLEN 256
  22. #define AES_ROUNDS 6
  23. class aes {
  24. protected:
  25. unsigned char* aesKey;
  26. unsigned char* aesIV;
  27. aes& clone(const aes& _e);
  28. void init_all();
  29. void clear_all();
  30. void setExtension(std::string _ex);
  31. private:
  32. std::string filename;
  33. std::string generateNewFilename();
  34. std::string getFilePath();
  35. std::string extension = ".new";
  36. public:
  37. aes() {};
  38. aes(std::string _filename);
  39. static std::string writeFile(unsigned char *file, size_t fileLength, const char* Filename);
  40. std::string writeFile(unsigned char *file, size_t fileLength);
  41. static int readFile(unsigned char** file, const char* filename);
  42. int readFile(unsigned char **file);
  43. std::string exportKey(const char* filename);
  44. std::string exportKey();
  45. void importKey(const char* filename);
  46. std::string PrintAesKey();
  47. void setAesIV(const unsigned char* _aesIV);
  48. void setAesKey(const unsigned char* _aesKey);
  49. unsigned char* getAesKey();
  50. unsigned char* getAesIV();
  51. virtual ~aes() = default;
  52. };
  53. aes::aes(std::string _filename) {
  54. filename = _filename;
  55. aesKey = (unsigned char*)malloc(AES_KEYLEN/8);
  56. aesIV = (unsigned char*)malloc(AES_KEYLEN/8);
  57. }
  58. aes& aes::clone(const aes& _e) {
  59. filename = _e.filename;
  60. setAesKey(_e.aesKey);
  61. setAesIV(_e.aesIV);
  62. return *this;
  63. }
  64. void aes::init_all() {
  65. unsigned char *aesPass = (unsigned char*)malloc(AES_KEYLEN/8);
  66. unsigned char *aesSalt = (unsigned char*)malloc(8);
  67. if(aesKey == NULL || aesIV == NULL || aesPass == NULL || aesSalt == NULL) {
  68. exit(FAILURE);
  69. }
  70. #define USE_PBKDF
  71. #ifdef USE_PBKDF
  72. std::cerr << "Use of USE_PBKDF parameter" << std::endl;
  73. // Get some random data to use as the AES pass and salt
  74. if(RAND_bytes(aesPass, AES_KEYLEN/8) == 0) {
  75. exit(FAILURE);
  76. }
  77. if(RAND_bytes(aesSalt, 8) == 0) {
  78. exit(FAILURE);
  79. }
  80. if(EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), aesSalt, aesPass, AES_KEYLEN/8, AES_ROUNDS, aesKey, aesIV) == 0) {
  81. exit(FAILURE);
  82. }
  83. #else
  84. if(RAND_bytes(aesKey, AES_KEYLEN/8) == 0) {
  85. exit(FAILURE);
  86. }
  87. if(RAND_bytes(aesIV, AES_KEYLEN/8) == 0) {
  88. exit(FAILURE);
  89. }
  90. #endif
  91. free(aesPass);
  92. free(aesSalt);
  93. }
  94. int aes::readFile(unsigned char** file) {
  95. return readFile(file, filename.c_str());
  96. }
  97. // peut être déporté le buffer lut avec methode pour travaillé dessus
  98. int aes::readFile(unsigned char** file, const char* filename) {
  99. FILE *fd = fopen(filename, "rb");
  100. if(fd == NULL) {
  101. fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
  102. exit(1);
  103. }
  104. // Determine size of the file
  105. fseek(fd, 0, SEEK_END);
  106. size_t fileLength = ftell(fd);
  107. fseek(fd, 0, SEEK_SET);
  108. // Allocate space for the file
  109. *file = (unsigned char*)malloc(fileLength); // @FIXME : failed for bigest file // maybe with new
  110. if(*file == NULL) {
  111. fprintf(stderr, "Failed to allocate memory\n");
  112. exit(1);
  113. }
  114. // Read the file into the buffer
  115. size_t bytesRead = fread(*file, 1, fileLength, fd);
  116. if(bytesRead != fileLength) {
  117. fprintf(stderr, "Error reading file\n");
  118. exit(1);
  119. }
  120. fclose(fd);
  121. return fileLength;
  122. }
  123. std::string aes::getFilePath() {
  124. std::regex e("\\b(.*[(\\.txt)]*)\\.[^(txt)].*");
  125. filename = std::regex_replace(filename, e,"$1");
  126. return filename;
  127. }
  128. std::string aes::generateNewFilename() {
  129. return aes::getFilePath()+extension;
  130. }
  131. std::string aes::writeFile(unsigned char *file, size_t fileLength) {
  132. std::string newFile = generateNewFilename();
  133. return writeFile(file, fileLength, newFile.c_str());
  134. }
  135. std::string aes::writeFile(unsigned char *file, size_t fileLength, const char* Filename) {
  136. FILE *fd = fopen(Filename, "wb");
  137. if(fd == NULL) {
  138. fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
  139. exit(1);
  140. }
  141. size_t bytesWritten = fwrite(file, 1, fileLength, fd);
  142. if(bytesWritten != fileLength) {
  143. fprintf(stderr, "Failed to write file\n");
  144. exit(1);
  145. }
  146. fclose(fd);
  147. return Filename;
  148. }
  149. void aes::setExtension(std::string _ex) {
  150. extension = _ex;
  151. }
  152. void aes::setAesKey(const unsigned char* _aesKey) {
  153. if(aesKey == NULL)
  154. aesKey = (unsigned char*)malloc(AES_KEYLEN/8);
  155. memcpy(aesKey , _aesKey, AES_KEYLEN/8);
  156. }
  157. void aes::setAesIV(const unsigned char* _aesIV) {
  158. if(aesIV == NULL)
  159. aesIV = (unsigned char*)malloc(AES_KEYLEN/8);
  160. memcpy(aesIV , _aesIV, AES_KEYLEN/8);
  161. }
  162. unsigned char* aes::getAesKey() {
  163. unsigned char* res = (unsigned char*)malloc(AES_KEYLEN/8);
  164. memcpy(res, aesKey, AES_KEYLEN/8);
  165. return res;
  166. }
  167. unsigned char* aes::getAesIV() {
  168. unsigned char* res = (unsigned char*)malloc(AES_KEYLEN/8);
  169. memcpy(res, aesIV, AES_KEYLEN/8);
  170. return res;
  171. }
  172. std::string aes::PrintAesKey() {
  173. std::stringstream ss;
  174. std::string res;
  175. res = "aesKey : ";
  176. res += base64_encode(aesKey, AES_KEYLEN/8);
  177. return res;
  178. }
  179. void aes::importKey(const char* filename) {
  180. Json::Value root;
  181. std::ifstream keyfile(filename, std::ifstream::binary);
  182. keyfile >> root;
  183. setAesKey(reinterpret_cast<const unsigned char*>(base64_decode(root["key"].asString()).c_str()));
  184. setAesIV(reinterpret_cast<const unsigned char*>(base64_decode(root["IV"].asString()).c_str()));
  185. }
  186. std::string aes::exportKey() {
  187. return exportKey((getFilePath()+".key").c_str());
  188. }
  189. std::string aes::exportKey(const char* filename) {
  190. // export the tuples aeskey and aesIV to json file
  191. Json::Value root;
  192. root["key"] = base64_encode(aesKey, AES_KEYLEN/8);
  193. root["IV"] = base64_encode(aesIV, AES_KEYLEN/8);
  194. std::ofstream out(filename);
  195. out << root;
  196. out.close();
  197. return std::string(filename);
  198. }
  199. void aes::clear_all() {
  200. free(aesIV);
  201. free(aesKey);
  202. }
  203. #endif