Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <iostream>
#include <fstream>
#include "certificates_loader.hh"
namespace fs = std::experimental::filesystem;
#include "converter.hh"
#include "loggers.hh"
certificates_loader * certificates_loader::instance = nullptr;
certificates_loader::certificates_loader(): _certificateExt{".crt"}, _privateKeyExt{".pkey"}, _publicKeysExt{".vkey"}, _full_path(), _is_cache_initialized{false}, _directory_filter{".svn", "._.DS_Store", ".DS_Store"} {
loggers::get_instance().log(">>> certificates_loader::certificates_loader");
} // End of ctor
int certificates_loader::build_path(const std::string& p_root_directory) {
loggers::get_instance().log(">>> certificates_loader::build_path: '%s'", p_root_directory.c_str());
// Build full path
if (!p_root_directory.empty()) {
_full_path = p_root_directory;
} else {
_full_path = "./";
}
fs::canonical(_full_path);
loggers::get_instance().log("certificates_loader::build_path: full path: %s", _full_path.string().c_str());
if (!fs::exists(_full_path)) {
loggers::get_instance().warning("certificates_loader::build_path: Invalid path");
_full_path.clear();
return -1;
}
return 0;
} // End of method build_path
int certificates_loader::load_certificates(std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s) {
loggers::get_instance().log(">>> certificates_loader::load_certificates");
// Sanity check
if (_full_path.empty()) {
return -1;
}
if (_is_cache_initialized) {
return 0;
}
// Retrieve the list of the files in the path
std::set<fs::path> files;
if (retrieve_certificates_list(files) == -1) {
return -1;
}
// Build the certificates cache
if (build_certificates_cache(files, p_certificates, p_hashed_id8s) == -1) {
return -1;
}
_is_cache_initialized = true;
return 0;
} // End of method load_certificates
int certificates_loader::retrieve_certificates_list(std::set<std::experimental::filesystem::path>& p_files) {
loggers::get_instance().log(">>> certificates_loader::retrieve_certificates_list");
// Walk through directories
std::set<fs::path> folders;
for (const fs::directory_entry it : fs::recursive_directory_iterator(_full_path.string())) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing directory '%s'", it.path().string().c_str());
if (fs::is_directory(it)) {
std::set<std::string>::const_iterator i = _directory_filter.find(it.path().filename());
if (i != _directory_filter.cend()) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Exclude directory '%s'", it.path().string().c_str());
continue;
}
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Add directory '%s'", it.path().string().c_str());
folders.insert(it.path());
}
} // End of 'for' statement
if (folders.size() == 0) {
loggers::get_instance().warning("certificates_loader::retrieve_certificates_list: No folder after filtering");
return -1;
}
// Process files
p_files.clear();
std::set<std::string> extensions_filter{ _certificateExt, _privateKeyExt, _publicKeysExt };
for (std::set<fs::path>::const_reverse_iterator f = folders.crbegin(); f != folders.crend(); ++f) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing directory '%s'", f->string().c_str());
for(const fs::directory_entry it : fs::recursive_directory_iterator(*f)) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing file '%s'", it.path().filename().string().c_str());
if (fs::is_regular_file(it)) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Check extension '%s'", it.path().extension().string().c_str());
std::set<std::string>::const_iterator i = extensions_filter.find(it.path().extension().string());
if (i != extensions_filter.cend()) {
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Add file '%s'", it.path().filename().string().c_str());
p_files.insert(it);
}
}
} // End of 'for' statement
} // End of 'for' statement
loggers::get_instance().log("certificates_loader::retrieve_certificates_list: # of files to cache:", p_files.size());
if (p_files.size() == 0) {
loggers::get_instance().warning("certificates_loader::retrieve_certificates_list: No certificate found");
return -1;
}
return 0;
} // End of method retrieve_certificates_list
int certificates_loader::build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s) {
loggers::get_instance().log(">>> certificates_loader::build_certificates_cache");
std::set<std::experimental::filesystem::path>::const_iterator it = p_files.cbegin();
do {
loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching '%s'", it->string().c_str());
fs::path p = *it;
std::string key = p.filename();
// Load certificate file
it = p_files.find(p.replace_extension(_certificateExt));
if (it == p_files.cend()) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Certificate file not found for '%s'", key.c_str());
return -1;
}
loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching certificate '%s'", it->string().c_str());
std::ifstream is(it->string(), ios::in | ios::binary);
std::vector<unsigned char> certificate(fs::file_size(*it), 0x00);
is.read(reinterpret_cast<char *>(certificate.data()), certificate.size());
is.close();
// Remove items from the list
p_files.erase(it);
// Load public key file
it = p_files.find(p.replace_extension(_publicKeysExt));
if (it == p_files.cend()) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Public keys file not found for '%s'", key.c_str());
return -1;
}
loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching public keys '%s'", it->string().c_str());
is.open(it->string(), ios::in | ios::binary);
int size = fs::file_size(*it);
if ((size != 64) && (size != 96)) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Public keys file not found for '%s'", key.c_str());
return -1;
}
std::vector<unsigned char> public_key_x(size / 2, 0x00);
is.read(reinterpret_cast<char *>(public_key_x.data()), public_key_x.size());
std::vector<unsigned char> public_key_y(size / 2, 0x00);
is.read(reinterpret_cast<char *>(public_key_y.data()), public_key_y.size());
is.close();
// Remove items from the list
p_files.erase(it);
// FIXME Caching private key, digest and issuer
// FIXME create new record
/*p_certificates.insert(std::pair<const std::string, std::unique_ptr<security_db_record> >(key, std::unique_ptr<security_db_record>(
new security_db_record(
key,
certificate, // Certificate
issuer, // Hashed ID fo the issuer, empty for CA
h, // Hashed ID
private_key, // Private key
public_key_x, // Public key X
public_key_y // Public key Y
))
));
std::map<const std::string, std::unique_ptr<security_db_record> >::const_iterator i = p_certificates.find(key);
if (i == _certificates.cend()) {
loggers::get_instance().warning("certificates_loader::build_certificates_cache: Failed to insert new record '%s'", key.c_str());
return -1;
}
p_hashed_id8s.insert(std::pair<const std::vector<unsigned char>, const std::string&>(i->second.get()->hashed_id(), i->first));*/
// Reset pointer
it = p_files.cbegin();
} while (it != p_files.cend());
return 0;
} // End of method build_certificates_cache