Decrypt file with callback for each entry.
583 {
584#ifdef LOGGER_HAS_OPENSSL_CRYPTO
585 std::ifstream input(input_path, std::ios::binary);
586 if (!input) {
587 return result<size_t>(
589 "Failed to open input file: " + input_path.string()
590 );
591 }
592
593 size_t entry_count = 0;
594 std::vector<uint8_t> buffer;
595
596 while (input.good()) {
597
598 encrypted_log_header header;
599 input.read(reinterpret_cast<char*>(&header), sizeof(header));
600
601 if (input.gcount() == 0) {
602 break;
603 }
604
605 if (input.gcount() != sizeof(header)) {
606 return result<size_t>(
608 "Incomplete header at entry " + std::to_string(entry_count)
609 );
610 }
611
612
614 return result<size_t>(
616 "Invalid magic number at entry " + std::to_string(entry_count)
617 );
618 }
619
620
621 buffer.resize(sizeof(header) + header.encrypted_length);
622 std::memcpy(buffer.data(), &header, sizeof(header));
623 input.read(
624 reinterpret_cast<char*>(buffer.data() + sizeof(header)),
625 header.encrypted_length
626 );
627
628 if (static_cast<size_t>(input.gcount()) != header.encrypted_length) {
629 return result<size_t>(
631 "Incomplete data at entry " + std::to_string(entry_count)
632 );
633 }
634
635
637 if (!decrypt_result.has_value()) {
638 return result<size_t>(
639 decrypt_result.error_code(),
640 "Decryption failed at entry " + std::to_string(entry_count) +
641 ": " + decrypt_result.error_message()
642 );
643 }
644
645 callback(decrypt_result.value());
646 ++entry_count;
647 }
648
649 return result<size_t>(entry_count);
650#else
651 return result<size_t>(
653 "OpenSSL not available - decryption disabled"
654 );
655#endif
656}
static result< std::string > decrypt_entry(const std::vector< uint8_t > &encrypted_data, const security::secure_key &key)
Decrypt a single encrypted log entry.