Skip to content

Commit d6cb5ca

Browse files
committed
refactor decryption frontend
1 parent 2a1d0c0 commit d6cb5ca

20 files changed

Lines changed: 153 additions & 143 deletions

cli/src/server.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ int main(int argc, char **argv) {
2121

2222
DecodedFile decoded_file{input, decode_preference};
2323

24-
if (decoded_file.is_document_file()) {
25-
DocumentFile document_file = decoded_file.document_file();
26-
if (document_file.password_encrypted() && !password) {
27-
std::cerr << "document encrypted but no password given" << std::endl;
28-
return 2;
29-
}
30-
if (document_file.password_encrypted() &&
31-
!document_file.decrypt(*password)) {
24+
if (decoded_file.password_encrypted() && !password) {
25+
std::cerr << "document encrypted but no password given" << std::endl;
26+
return 2;
27+
}
28+
if (decoded_file.password_encrypted()) {
29+
auto decrypt_result = decoded_file.decrypt(*password);
30+
if (!decrypt_result.has_value()) {
3231
std::cerr << "wrong password" << std::endl;
3332
return 1;
3433
}
34+
decoded_file = std::move(*decrypt_result);
3535
}
3636

3737
HttpServer::Config server_config;

cli/src/translate.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ int main(int argc, char **argv) {
1919

2020
DecodedFile decoded_file{input};
2121

22-
if (decoded_file.is_document_file()) {
23-
DocumentFile document_file = decoded_file.document_file();
24-
if (document_file.password_encrypted() && !password) {
25-
std::cerr << "document encrypted but no password given" << std::endl;
26-
return 2;
27-
}
28-
if (document_file.password_encrypted() &&
29-
!document_file.decrypt(*password)) {
22+
if (decoded_file.password_encrypted() && !password) {
23+
std::cerr << "document encrypted but no password given" << std::endl;
24+
return 2;
25+
}
26+
if (decoded_file.password_encrypted()) {
27+
auto decrypt_result = decoded_file.decrypt(*password);
28+
if (!decrypt_result.has_value()) {
3029
std::cerr << "wrong password" << std::endl;
3130
return 1;
3231
}
32+
decoded_file = std::move(*decrypt_result);
3333
}
3434

3535
HtmlConfig config;

src/odr/file.cpp

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ File::File(std::shared_ptr<internal::abstract::File> impl)
3535
File::File(const std::string &path)
3636
: m_impl{std::make_shared<internal::common::DiskFile>(path)} {}
3737

38-
File::operator bool() const { return m_impl.operator bool(); }
39-
4038
FileLocation File::location() const noexcept { return m_impl->location(); }
4139

4240
std::size_t File::size() const { return m_impl->size(); }
@@ -107,7 +105,7 @@ DecodedFile::DecodedFile(const std::string &path,
107105
: DecodedFile(internal::open_strategy::open_file(
108106
std::make_shared<internal::common::DiskFile>(path), preference)) {}
109107

110-
DecodedFile::operator bool() const { return m_impl.operator bool(); }
108+
File DecodedFile::file() const { return File(m_impl->file()); }
111109

112110
FileType DecodedFile::file_type() const noexcept { return m_impl->file_type(); }
113111

@@ -121,7 +119,21 @@ DecoderEngine DecodedFile::decoder_engine() const noexcept {
121119
return m_impl->decoder_engine();
122120
}
123121

124-
File DecodedFile::file() const { return File(m_impl->file()); }
122+
bool DecodedFile::password_encrypted() const {
123+
return m_impl->password_encrypted();
124+
}
125+
126+
EncryptionState DecodedFile::encryption_state() const {
127+
return m_impl->encryption_state();
128+
}
129+
130+
std::optional<DecodedFile> DecodedFile::decrypt(const std::string &password) {
131+
auto decrypted = m_impl->decrypt(password);
132+
if (decrypted == nullptr) {
133+
return std::nullopt;
134+
}
135+
return DecodedFile(decrypted);
136+
}
125137

126138
bool DecodedFile::is_text_file() const {
127139
return std::dynamic_pointer_cast<internal::abstract::TextFile>(m_impl) !=
@@ -231,18 +243,6 @@ DocumentFile::DocumentFile(const std::string &path)
231243
: DocumentFile(internal::open_strategy::open_document_file(
232244
std::make_shared<internal::common::DiskFile>(path))) {}
233245

234-
bool DocumentFile::password_encrypted() const {
235-
return m_impl->password_encrypted();
236-
}
237-
238-
EncryptionState DocumentFile::encryption_state() const {
239-
return m_impl->encryption_state();
240-
}
241-
242-
bool DocumentFile::decrypt(const std::string &password) {
243-
return m_impl->decrypt(password);
244-
}
245-
246246
DocumentType DocumentFile::document_type() const {
247247
return m_impl->document_type();
248248
}
@@ -260,18 +260,6 @@ std::shared_ptr<internal::abstract::DocumentFile> DocumentFile::impl() const {
260260
PdfFile::PdfFile(std::shared_ptr<internal::abstract::PdfFile> impl)
261261
: DecodedFile(impl), m_impl{std::move(impl)} {}
262262

263-
bool PdfFile::password_encrypted() const {
264-
return m_impl->password_encrypted();
265-
}
266-
267-
EncryptionState PdfFile::encryption_state() const {
268-
return m_impl->encryption_state();
269-
}
270-
271-
bool PdfFile::decrypt(const std::string &password) {
272-
return m_impl->decrypt(password);
273-
}
274-
275263
std::shared_ptr<internal::abstract::PdfFile> PdfFile::impl() const {
276264
return m_impl;
277265
}

src/odr/file.hpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ class File final {
154154
explicit File(std::shared_ptr<internal::abstract::File>);
155155
explicit File(const std::string &path);
156156

157-
[[nodiscard]] explicit operator bool() const;
158-
159157
[[nodiscard]] FileLocation location() const noexcept;
160158
[[nodiscard]] std::size_t size() const;
161159

@@ -189,14 +187,16 @@ class DecodedFile {
189187
DecodedFile(const std::string &path, FileType as);
190188
DecodedFile(const std::string &path, const DecodePreference &preference);
191189

192-
[[nodiscard]] explicit operator bool() const;
190+
[[nodiscard]] File file() const;
193191

194192
[[nodiscard]] FileType file_type() const noexcept;
195193
[[nodiscard]] FileCategory file_category() const noexcept;
196194
[[nodiscard]] FileMeta file_meta() const noexcept;
197195
[[nodiscard]] DecoderEngine decoder_engine() const noexcept;
198196

199-
[[nodiscard]] File file() const;
197+
[[nodiscard]] bool password_encrypted() const;
198+
[[nodiscard]] EncryptionState encryption_state() const;
199+
[[nodiscard]] std::optional<DecodedFile> decrypt(const std::string &password);
200200

201201
[[nodiscard]] bool is_text_file() const;
202202
[[nodiscard]] bool is_image_file() const;
@@ -259,10 +259,6 @@ class DocumentFile final : public DecodedFile {
259259
explicit DocumentFile(std::shared_ptr<internal::abstract::DocumentFile>);
260260
explicit DocumentFile(const std::string &path);
261261

262-
[[nodiscard]] bool password_encrypted() const;
263-
[[nodiscard]] EncryptionState encryption_state() const;
264-
bool decrypt(const std::string &password);
265-
266262
[[nodiscard]] DocumentType document_type() const;
267263
[[nodiscard]] DocumentMeta document_meta() const;
268264

@@ -279,10 +275,6 @@ class PdfFile final : public DecodedFile {
279275
public:
280276
explicit PdfFile(std::shared_ptr<internal::abstract::PdfFile>);
281277

282-
[[nodiscard]] bool password_encrypted() const;
283-
[[nodiscard]] EncryptionState encryption_state() const;
284-
bool decrypt(const std::string &password);
285-
286278
[[nodiscard]] std::shared_ptr<internal::abstract::PdfFile> impl() const;
287279

288280
private:

src/odr/internal/abstract/file.hpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ class DecodedFile {
3838
[[nodiscard]] virtual FileCategory file_category() const noexcept = 0;
3939
[[nodiscard]] virtual FileMeta file_meta() const noexcept = 0;
4040
[[nodiscard]] virtual DecoderEngine decoder_engine() const noexcept = 0;
41+
42+
[[nodiscard]] virtual bool password_encrypted() const noexcept {
43+
return false;
44+
}
45+
[[nodiscard]] virtual EncryptionState encryption_state() const noexcept {
46+
return EncryptionState::not_encrypted;
47+
}
48+
[[nodiscard]] virtual std::shared_ptr<DecodedFile>
49+
decrypt(const std::string &password) const noexcept {
50+
return nullptr;
51+
}
4152
};
4253

4354
class TextFile : public DecodedFile {
@@ -71,10 +82,6 @@ class DocumentFile : public DecodedFile {
7182
return FileCategory::document;
7283
}
7384

74-
[[nodiscard]] virtual bool password_encrypted() const noexcept = 0;
75-
[[nodiscard]] virtual EncryptionState encryption_state() const noexcept = 0;
76-
[[nodiscard]] virtual bool decrypt(const std::string &password) = 0;
77-
7885
[[nodiscard]] virtual DocumentType document_type() const = 0;
7986
[[nodiscard]] virtual DocumentMeta document_meta() const = 0;
8087

@@ -89,10 +96,6 @@ class PdfFile : public DecodedFile {
8996
[[nodiscard]] FileCategory file_category() const noexcept final {
9097
return FileCategory::document;
9198
}
92-
93-
[[nodiscard]] virtual bool password_encrypted() const noexcept = 0;
94-
[[nodiscard]] virtual EncryptionState encryption_state() const noexcept = 0;
95-
[[nodiscard]] virtual bool decrypt(const std::string &password) = 0;
9699
};
97100

98101
} // namespace odr::internal::abstract

src/odr/internal/odf/odf_crypto.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -163,29 +163,28 @@ class DecryptedFilesystem final : public abstract::ReadableFilesystem {
163163
} // namespace
164164
} // namespace odf
165165

166-
bool odf::decrypt(std::shared_ptr<abstract::ReadableFilesystem> &storage,
167-
const Manifest &manifest, const std::string &password) {
166+
std::shared_ptr<abstract::ReadableFilesystem>
167+
odf::decrypt(const std::shared_ptr<abstract::ReadableFilesystem> &filesystem,
168+
const Manifest &manifest, const std::string &password) {
168169
if (!manifest.encrypted) {
169-
return true;
170+
return nullptr;
170171
}
171172

172173
if (auto it = manifest.entries.find(common::Path("encrypted-package"));
173174
it != std::end(manifest.entries)) {
174175
try {
175176
const std::string start_key = odf::start_key(it->second, password);
176177
const std::string input =
177-
util::stream::read(*storage->open(it->first)->stream());
178+
util::stream::read(*filesystem->open(it->first)->stream());
178179
std::string decrypt = crypto::util::inflate(
179180
derive_key_and_decrypt(it->second, start_key, input));
180181

181182
auto memory_file =
182183
std::make_shared<common::MemoryFile>(std::move(decrypt));
183-
storage = zip::ZipFile(memory_file).archive()->filesystem();
184+
return zip::ZipFile(memory_file).archive()->filesystem();
184185
} catch (...) {
185-
return false;
186+
return nullptr;
186187
}
187-
188-
return true;
189188
}
190189

191190
try {
@@ -197,19 +196,17 @@ bool odf::decrypt(std::shared_ptr<abstract::ReadableFilesystem> &storage,
197196
const std::string start_key = odf::start_key(smallest_file_entry, password);
198197
// TODO stream decrypt
199198
const std::string input =
200-
util::stream::read(*storage->open(smallest_file_path)->stream());
199+
util::stream::read(*filesystem->open(smallest_file_path)->stream());
201200
const std::string decrypt =
202201
derive_key_and_decrypt(smallest_file_entry, start_key, input);
203202
if (!validate_password(smallest_file_entry, decrypt)) {
204-
return false;
203+
return nullptr;
205204
}
206-
storage = std::make_shared<DecryptedFilesystem>(std::move(storage),
207-
manifest, start_key);
205+
return std::make_shared<DecryptedFilesystem>(filesystem, manifest,
206+
start_key);
208207
} catch (...) {
209-
return false;
208+
return nullptr;
210209
}
211-
212-
return true;
213210
}
214211

215212
} // namespace odr::internal

src/odr/internal/odf/odf_crypto.hpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,29 @@ class ReadableFilesystem;
1313

1414
namespace odr::internal::odf {
1515

16-
bool can_decrypt(const Manifest::Entry &) noexcept;
16+
bool can_decrypt(const Manifest::Entry &entry) noexcept;
1717

1818
std::string hash(const std::string &input, ChecksumType checksum_type);
1919

2020
std::string decrypt(const std::string &input, const std::string &derived_key,
2121
const std::string &initialisation_vector,
2222
AlgorithmType algorithm);
2323

24-
std::string start_key(const Manifest::Entry &, const std::string &password);
24+
std::string start_key(const Manifest::Entry &entry,
25+
const std::string &password);
2526

26-
std::string derive_key(const Manifest::Entry &, const std::string &start_key);
27+
std::string derive_key(const Manifest::Entry &entry,
28+
const std::string &start_key);
2729

28-
std::string derive_key_and_decrypt(const Manifest::Entry &,
30+
std::string derive_key_and_decrypt(const Manifest::Entry &entry,
2931
const std::string &start_key,
3032
const std::string &input);
3133

32-
bool validate_password(const Manifest::Entry &, std::string decrypted) noexcept;
34+
bool validate_password(const Manifest::Entry &entry,
35+
std::string decrypted) noexcept;
3336

34-
bool decrypt(std::shared_ptr<abstract::ReadableFilesystem> &, const Manifest &,
35-
const std::string &password);
37+
std::shared_ptr<abstract::ReadableFilesystem>
38+
decrypt(const std::shared_ptr<abstract::ReadableFilesystem> &filesystem,
39+
const Manifest &manifest, const std::string &password);
3640

3741
} // namespace odr::internal::odf

src/odr/internal/odf/odf_file.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,23 @@ EncryptionState OpenDocumentFile::encryption_state() const noexcept {
6262
return m_encryption_state;
6363
}
6464

65-
bool OpenDocumentFile::decrypt(const std::string &password) {
66-
// TODO throw if not encrypted or already decrypted
67-
if (!odf::decrypt(m_filesystem, m_manifest, password)) {
68-
return false;
65+
std::shared_ptr<abstract::DecodedFile>
66+
OpenDocumentFile::decrypt(const std::string &password) const noexcept {
67+
if (m_encryption_state != EncryptionState::encrypted) {
68+
return nullptr;
6969
}
70-
m_file_meta = parse_file_meta(*m_filesystem, nullptr, true);
71-
m_encryption_state = EncryptionState::decrypted;
72-
return true;
70+
71+
auto decrypted_filesystem = odf::decrypt(m_filesystem, m_manifest, password);
72+
if (decrypted_filesystem == nullptr) {
73+
return nullptr;
74+
}
75+
76+
auto decrypted_file = std::make_shared<OpenDocumentFile>(*this);
77+
decrypted_file->m_filesystem = std::move(decrypted_filesystem);
78+
decrypted_file->m_file_meta =
79+
parse_file_meta(*decrypted_file->m_filesystem, nullptr, true);
80+
decrypted_file->m_encryption_state = EncryptionState::decrypted;
81+
return std::move(decrypted_file);
7382
}
7483

7584
std::shared_ptr<abstract::Document> OpenDocumentFile::document() const {

src/odr/internal/odf/odf_file.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class OpenDocumentFile final : public virtual abstract::DocumentFile {
3434

3535
[[nodiscard]] bool password_encrypted() const noexcept final;
3636
[[nodiscard]] EncryptionState encryption_state() const noexcept final;
37-
bool decrypt(const std::string &password) final;
37+
[[nodiscard]] std::shared_ptr<abstract::DecodedFile>
38+
decrypt(const std::string &password) const noexcept final;
3839

3940
[[nodiscard]] std::shared_ptr<abstract::Document> document() const final;
4041

src/odr/internal/oldms/oldms_file.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ EncryptionState LegacyMicrosoftFile::encryption_state() const noexcept {
7777
return EncryptionState::unknown;
7878
}
7979

80-
bool LegacyMicrosoftFile::decrypt(const std::string &) {
81-
return false; // TODO throw
80+
std::shared_ptr<abstract::DecodedFile>
81+
LegacyMicrosoftFile::decrypt(const std::string &password) const noexcept {
82+
return {}; // TODO throw
8283
}
8384

8485
std::shared_ptr<abstract::Document> LegacyMicrosoftFile::document() const {

0 commit comments

Comments
 (0)