1 #pragma once 2 #include <memory> 3 #include <string> 4 #include <unordered_map> 5 #include <vector> 6 7 #include "json.hpp" 8 // for convenience 9 using json = nlohmann::json; 10 11 struct KeychainField { 12 std::string name; 13 std::string value; 14 std::string type; 15 bool password; 16 }; 17 18 struct KeychainItem { 19 std::string title; 20 std::string uuid; 21 std::string category; 22 std::string folder; 23 std::unordered_map<std::string, std::vector<KeychainField>> sections; addFieldKeychainItem24 void addField(std::string section, KeychainField field) { 25 auto it = sections.find(section); 26 if (it == sections.end()) { 27 sections.emplace(std::make_pair(section, std::vector<KeychainField>{field})); 28 } else { 29 it->second.push_back(std::move(field)); 30 } 31 } 32 std::vector<std::string> URLs; 33 std::string website; 34 std::string notes; 35 }; 36 37 class AgileKeychainMasterKey { 38 public: 39 AgileKeychainMasterKey(const json& input, const std::string masterPassword); 40 41 json decryptItem(const json& input); 42 json decryptJSON(const std::string& input); 43 std::string encryptJSON(const json& input); 44 45 std::string level; 46 std::string id; 47 48 private: 49 std::vector<uint8_t> key_data; 50 }; 51 52 class Keychain { 53 public: 54 Keychain(std::string path, std::string masterPassword); 55 56 using ItemMap = std::unordered_map<std::string, KeychainItem>; begin()57 ItemMap::iterator begin() { 58 if (!loaded) 59 reloadItems(); 60 return items.begin(); 61 } 62 end()63 ItemMap::iterator end() { 64 if (!loaded) 65 reloadItems(); 66 return items.end(); 67 } 68 find(std::string key)69 ItemMap::iterator find(std::string key) { 70 if (!loaded) 71 reloadItems(); 72 return items.find(key); 73 } 74 75 void reloadItems(); 76 void unloadItems(); 77 getTitle()78 std::string getTitle() { 79 return title; 80 } 81 decryptJSON(const std::string & input)82 json decryptJSON(const std::string& input) { 83 return level5_key->decryptJSON(input); 84 } 85 encryptJSON(const json & input)86 std::string encryptJSON(const json& input) { 87 return level5_key->encryptJSON(input); 88 } 89 90 private: 91 void loadItem(std::string uuid); 92 93 ItemMap items; 94 std::unique_ptr<AgileKeychainMasterKey> level3_key, level5_key; 95 std::string vault_path; 96 std::string title; 97 bool loaded = false; 98 }; 99