diff --git a/src/attachments.cpp b/src/attachments.cpp index d2a32283..29e885be 100644 --- a/src/attachments.cpp +++ b/src/attachments.cpp @@ -301,7 +301,10 @@ std::array encrypt( const std::filesystem::path& file, Domain domain, std::function(size_t enc_size)> make_buffer, - bool /*allow_large*/) { + bool allow_large) { + + if (seed.size() < 32) + throw std::invalid_argument{"attachment::encrypt requires a 32-byte uploader seed"}; std::ifstream in; in.exceptions(std::ios::badbit); @@ -309,6 +312,9 @@ std::array encrypt( size_t size = in.tellg(); in.seekg(0, std::ios::beg); + if (size > MAX_REGULAR_SIZE && !allow_large) + throw std::invalid_argument{"data to encrypt is too large"}; + size = encrypted_size(size); std::array nonce_key; diff --git a/tests/test_attachment_encrypt.cpp b/tests/test_attachment_encrypt.cpp index 91f18ef4..684fad8d 100644 --- a/tests/test_attachment_encrypt.cpp +++ b/tests/test_attachment_encrypt.cpp @@ -247,6 +247,26 @@ TEST_CASE( CHECK(!!(decr == make_data(DATA_SIZE))); } +TEST_CASE("Attachment file encryption validates its inputs", "[attachments][files][encrypt]") { + auto seed = "5123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"_hex_b; + temp_data_file f{0}; + + CHECK_THROWS_MATCHES( + attachment::encrypt( + std::span{seed}.first<31>(), f.path, attachment::Domain::ATTACHMENT), + std::invalid_argument, + Message("attachment::encrypt requires a 32-byte uploader seed")); + + std::filesystem::resize_file(f.path, attachment::MAX_REGULAR_SIZE + 1); + CHECK_THROWS_MATCHES( + attachment::encrypt(seed, f.path, attachment::Domain::ATTACHMENT), + std::invalid_argument, + Message("data to encrypt is too large")); + + auto [enc, key] = attachment::encrypt(seed, f.path, attachment::Domain::ATTACHMENT, true); + CHECK(attachment::decrypt(enc, key).size() == attachment::MAX_REGULAR_SIZE + 1); +} + static std::vector slurp_file(const std::filesystem::path& filename) { std::ifstream in; in.exceptions(std::ios::failbit | std::ios::badbit);