mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
intermediate commit
This commit is contained in:
parent
2fc692d694
commit
126f22816b
|
@ -27,24 +27,26 @@
|
|||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
using byte = std::uint8_t;
|
||||
|
||||
class byte_reader
|
||||
class binary_reader
|
||||
{
|
||||
public:
|
||||
byte_reader() = delete;
|
||||
binary_reader() = delete;
|
||||
|
||||
byte_reader(const std::vector<byte> &bytes)
|
||||
binary_reader(const std::vector<byte> &bytes)
|
||||
: bytes_(&bytes)
|
||||
{
|
||||
}
|
||||
|
||||
byte_reader(const byte_reader &other) = default;
|
||||
binary_reader(const binary_reader &other) = default;
|
||||
|
||||
byte_reader &operator=(const byte_reader &other)
|
||||
binary_reader &operator=(const binary_reader &other)
|
||||
{
|
||||
offset_ = other.offset_;
|
||||
bytes_ = other.bytes_;
|
||||
|
@ -52,7 +54,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
~byte_reader()
|
||||
~binary_reader()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ public:
|
|||
template<typename T>
|
||||
std::vector<T> as_vector_of() const
|
||||
{
|
||||
auto result = std::vector<T>(size() / sizeof(T), 0);
|
||||
auto result = std::vector<T>(size() / sizeof(T), T());
|
||||
std::memcpy(result.data(), bytes_->data(), size());
|
||||
|
||||
return result;
|
||||
|
@ -105,108 +107,59 @@ private:
|
|||
const std::vector<std::uint8_t> *bytes_;
|
||||
};
|
||||
|
||||
class byte_vector
|
||||
class binary_writer
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
static byte_vector from(const std::vector<T> &ints)
|
||||
{
|
||||
byte_vector result;
|
||||
|
||||
result.resize(ints.size() * sizeof(T));
|
||||
std::memcpy(result.bytes_.data(), ints.data(), result.bytes_.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static byte_vector from(const std::basic_string<T> &string)
|
||||
{
|
||||
byte_vector result;
|
||||
|
||||
result.resize(string.size() * sizeof(T));
|
||||
std::memcpy(result.bytes_.data(), string.data(), result.bytes_.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
byte_vector()
|
||||
: reader_(bytes_)
|
||||
binary_writer(std::vector<byte> &bytes)
|
||||
: bytes_(&bytes)
|
||||
{
|
||||
}
|
||||
|
||||
byte_vector(std::vector<byte> &bytes)
|
||||
: bytes_(bytes),
|
||||
reader_(bytes_)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
byte_vector(const std::vector<T> &ints)
|
||||
: byte_vector()
|
||||
{
|
||||
bytes_ = from(ints).data();
|
||||
}
|
||||
|
||||
byte_vector(const byte_vector &other)
|
||||
: byte_vector()
|
||||
binary_writer(const binary_writer &other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
~byte_vector()
|
||||
~binary_writer()
|
||||
{
|
||||
}
|
||||
|
||||
byte_vector &operator=(const byte_vector &other)
|
||||
binary_writer &operator=(const binary_writer &other)
|
||||
{
|
||||
bytes_ = other.bytes_;
|
||||
reader_ = byte_reader(bytes_);
|
||||
offset_ = other.offset_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::vector<byte> &data() const
|
||||
|
||||
template<typename T>
|
||||
void assign(const std::vector<T> &ints)
|
||||
{
|
||||
return bytes_;
|
||||
resize(ints.size() * sizeof(T));
|
||||
std::memcpy(bytes_->data(), ints.data(), bytes_->size());
|
||||
}
|
||||
|
||||
std::vector<byte> data()
|
||||
template<typename T>
|
||||
void assign(const std::basic_string<T> &string)
|
||||
{
|
||||
return bytes_;
|
||||
resize(string.size() * sizeof(T));
|
||||
std::memcpy(bytes_->data(), string.data(), bytes_->size());
|
||||
}
|
||||
|
||||
void data(std::vector<byte> &bytes)
|
||||
void offset(std::size_t new_offset)
|
||||
{
|
||||
bytes_ = bytes;
|
||||
}
|
||||
|
||||
void offset(std::size_t offset)
|
||||
{
|
||||
reader_.offset(offset);
|
||||
offset_ = new_offset;
|
||||
}
|
||||
|
||||
std::size_t offset() const
|
||||
{
|
||||
return reader_.offset();
|
||||
return offset_;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
reader_.reset();
|
||||
bytes_.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T read()
|
||||
{
|
||||
return reader_.read<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> as_vector_of() const
|
||||
{
|
||||
return reader_.as_vector_of<T>();
|
||||
offset_ = 0;
|
||||
bytes_->clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -219,35 +172,47 @@ public:
|
|||
extend(offset() + num_bytes - size());
|
||||
}
|
||||
|
||||
std::memcpy(bytes_.data() + offset(), &value, num_bytes);
|
||||
reader_.offset(reader_.offset() + num_bytes);
|
||||
std::memcpy(bytes_->data() + offset(), &value, num_bytes);
|
||||
offset_ += num_bytes;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return bytes_.size();
|
||||
return bytes_->size();
|
||||
}
|
||||
|
||||
void resize(std::size_t new_size, byte fill = 0)
|
||||
{
|
||||
bytes_.resize(new_size, fill);
|
||||
bytes_->resize(new_size, fill);
|
||||
}
|
||||
|
||||
void extend(std::size_t amount, byte fill = 0)
|
||||
{
|
||||
bytes_.resize(size() + amount, fill);
|
||||
bytes_->resize(size() + amount, fill);
|
||||
}
|
||||
|
||||
std::vector<byte>::iterator iterator()
|
||||
{
|
||||
return bytes_.begin() + static_cast<std::ptrdiff_t>(offset());
|
||||
return bytes_->begin() + static_cast<std::ptrdiff_t>(offset());
|
||||
}
|
||||
|
||||
void append(const std::vector<std::uint8_t> &data, std::size_t offset, std::size_t count)
|
||||
{
|
||||
auto end_index = size();
|
||||
extend(count);
|
||||
std::memcpy(bytes_.data() + end_index, data.data() + offset, count);
|
||||
std::memcpy(bytes_->data() + end_index, data.data() + offset, count);
|
||||
}
|
||||
|
||||
void append(const byte *data, const std::size_t data_size, std::size_t offset, std::size_t count)
|
||||
{
|
||||
if (offset + count > data_size)
|
||||
{
|
||||
throw xlnt::exception("out of bounds read");
|
||||
}
|
||||
|
||||
const auto end_index = size();
|
||||
extend(count);
|
||||
std::memcpy(bytes_->data() + end_index, data + offset, count);
|
||||
}
|
||||
|
||||
void append(const std::vector<std::uint8_t> &data)
|
||||
|
@ -256,9 +221,19 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
std::vector<byte> bytes_;
|
||||
byte_reader reader_;
|
||||
std::vector<byte> *bytes_;
|
||||
std::size_t offset_ = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::vector<byte> string_to_bytes(const std::basic_string<T> &string)
|
||||
{
|
||||
std::vector<byte> bytes;
|
||||
binary_writer writer(bytes);
|
||||
writer.assign(string);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -31,13 +31,15 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <detail/bytes.hpp>
|
||||
#include <detail/binary.hpp>
|
||||
#include <detail/cryptography/compound_document.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
using xlnt::detail::byte_vector;
|
||||
using xlnt::detail::byte;
|
||||
using xlnt::detail::binary_reader;
|
||||
using xlnt::detail::binary_writer;
|
||||
|
||||
using directory_id = std::int32_t;
|
||||
using sector_id = std::int32_t;
|
||||
|
@ -124,14 +126,11 @@ public:
|
|||
return chain;
|
||||
}
|
||||
|
||||
void load(const byte_vector &data)
|
||||
void load(std::size_t new_sector_size, const std::vector<byte> §ors)
|
||||
{
|
||||
data_ = data.as_vector_of<sector_id>();
|
||||
}
|
||||
|
||||
byte_vector save() const
|
||||
{
|
||||
return byte_vector::from(data_);
|
||||
sector_size(new_sector_size);
|
||||
auto reader = binary_reader(sectors);
|
||||
data_ = reader.as_vector_of<sector_id>();
|
||||
}
|
||||
|
||||
std::size_t sector_size() const
|
||||
|
@ -174,14 +173,14 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void load(byte_vector &data)
|
||||
void load(binary_reader &reader)
|
||||
{
|
||||
if (data.size() < 512)
|
||||
if (reader.size() < 512)
|
||||
{
|
||||
throw xlnt::exception("bad header");
|
||||
}
|
||||
|
||||
*this = data.read<header>();
|
||||
*this = reader.read<header>();
|
||||
|
||||
if (file_id_ != 0xe11ab1a1e011cfd0)
|
||||
{
|
||||
|
@ -194,14 +193,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
byte_vector save() const
|
||||
{
|
||||
byte_vector out;
|
||||
out.write(*this);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::size_t sector_size() const
|
||||
{
|
||||
return std::size_t(1) << sector_size_power_;
|
||||
|
@ -436,43 +427,17 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void load(byte_vector &data)
|
||||
void load(const std::vector<byte> &data)
|
||||
{
|
||||
entries.clear();
|
||||
|
||||
auto num_entries = data.size() / sizeof(directory_entry);
|
||||
|
||||
for (auto i = std::size_t(0); i < num_entries; ++i)
|
||||
auto reader = binary_reader(data);
|
||||
entries = reader.as_vector_of<directory_entry>();
|
||||
|
||||
auto is_empty = [](const directory_entry &entry)
|
||||
{
|
||||
auto e = data.read<directory_entry>();
|
||||
return entry.type == directory_entry::entry_type::Empty;
|
||||
};
|
||||
|
||||
if (e.type == directory_entry::entry_type::Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((e.type != directory_entry::entry_type::UserStream)
|
||||
&& (e.type != directory_entry::entry_type::UserStorage)
|
||||
&& (e.type != directory_entry::entry_type::RootStorage))
|
||||
{
|
||||
throw xlnt::exception("invalid entry");
|
||||
}
|
||||
|
||||
entries.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
byte_vector save() const
|
||||
{
|
||||
auto result = byte_vector();
|
||||
|
||||
for (auto &entry : entries)
|
||||
{
|
||||
result.write(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
entries.erase(std::remove_if(entries.begin(), entries.end(), is_empty));
|
||||
}
|
||||
|
||||
directory_entry create_root_entry() const
|
||||
|
@ -606,62 +571,72 @@ namespace detail {
|
|||
class compound_document_reader_impl
|
||||
{
|
||||
public:
|
||||
compound_document_reader_impl(const std::vector<std::uint8_t> &data)
|
||||
compound_document_reader_impl(const std::vector<byte> &bytes)
|
||||
: sectors_(bytes.data() + sizeof(header)),
|
||||
sectors_size_(bytes.size())
|
||||
{
|
||||
auto reader = byte_vector(data);
|
||||
auto reader = binary_reader(bytes);
|
||||
|
||||
header_.load(reader);
|
||||
|
||||
sector_table_.sector_size(header_.sector_size());
|
||||
short_sector_table_.sector_size(header_.short_sector_size());
|
||||
const auto sector_size = header_.sector_size();
|
||||
const auto master_table_chain = load_master_table();
|
||||
const auto master_sectors = read(master_table_chain);
|
||||
sector_table_.load(sector_size, master_sectors);
|
||||
|
||||
sectors_.append(data, 512, data.size() - 512);
|
||||
const auto short_sector_size = header_.short_sector_size();
|
||||
const auto short_start = header_.short_table_start();
|
||||
const auto short_table_chain = sector_table_.follow(short_start);
|
||||
const auto short_sectors = read(short_table_chain);
|
||||
short_sector_table_.load(short_sector_size, short_sectors);
|
||||
|
||||
sector_table_.load(load_sectors(load_msat(reader)));
|
||||
short_sector_table_.load(load_sectors(sector_table_.follow(header_.short_table_start())));
|
||||
auto directory_data = load_sectors(sector_table_.follow(header_.directory_start()));
|
||||
directory_.load(directory_data);
|
||||
const auto directory_start = header_.directory_start();
|
||||
const auto directory_chain = sector_table_.follow(directory_start);
|
||||
const auto directory_sectors = read(directory_chain);
|
||||
directory_.load(directory_sectors);
|
||||
|
||||
auto first_short_sector = directory_.entry(u"/Root Entry", false).first;
|
||||
short_container_stream_ = sector_table_.follow(first_short_sector);
|
||||
}
|
||||
|
||||
byte_vector load_sectors(const std::vector<sector_id> §ors) const
|
||||
std::vector<byte> read(const std::vector<sector_id> §ors) const
|
||||
{
|
||||
auto result = byte_vector();
|
||||
const auto sector_size = sector_table_.sector_size();
|
||||
auto result = std::vector<byte>();
|
||||
auto writer = binary_writer(result);
|
||||
|
||||
for (auto sector : sectors)
|
||||
{
|
||||
auto position = sector_size * static_cast<std::size_t>(sector);
|
||||
result.append(sectors_.data(), position, sector_size);
|
||||
auto position = sizeof(header) + sector_size * static_cast<std::size_t>(sector);
|
||||
writer.append(sectors_, sectors_size_, position, sector_size);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
byte_vector load_short_sectors(const std::vector<sector_id> §ors) const
|
||||
std::vector<byte> read_short(const std::vector<sector_id> §ors) const
|
||||
{
|
||||
auto result = byte_vector();
|
||||
const auto short_sector_size = short_sector_table_.sector_size();
|
||||
const auto sector_size = sector_table_.sector_size();
|
||||
auto result = std::vector<byte>();
|
||||
auto writer = binary_writer(result);
|
||||
|
||||
for (auto sector : sectors)
|
||||
{
|
||||
auto position = short_sector_size * static_cast<std::size_t>(sector);
|
||||
auto master_allocation_table_index = position / sector_size;
|
||||
|
||||
auto sector_data = load_sectors({ short_container_stream_[master_allocation_table_index] });
|
||||
auto sector_data = read({ short_container_stream_[master_allocation_table_index] });
|
||||
|
||||
auto offset = position % sector_size;
|
||||
result.append(sector_data.data(), offset, short_sector_size);
|
||||
writer.append(sector_data, offset, short_sector_size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<sector_id> load_msat(byte_vector &/*data*/)
|
||||
std::vector<sector_id> load_master_table()
|
||||
{
|
||||
const auto sector_size = header_.sector_size();
|
||||
auto master_sectors = header_.sectors();
|
||||
|
||||
if (header_.num_master_sectors() > 109)
|
||||
|
@ -670,60 +645,56 @@ public:
|
|||
|
||||
for (auto r = std::size_t(0); r < header_.num_master_sectors(); ++r)
|
||||
{
|
||||
auto msat = load_sectors({ current_sector });
|
||||
auto index = sector_id(0);
|
||||
|
||||
while (index < static_cast<sector_id>((sector_size - 1) / sizeof(sector_id)))
|
||||
{
|
||||
master_sectors.push_back(msat.read<sector_id>());
|
||||
}
|
||||
|
||||
current_sector = msat.read<sector_id>();
|
||||
auto current_sector_data = read({ current_sector });
|
||||
auto current_sector_reader = binary_reader(current_sector_data);
|
||||
auto current_sector_sectors = current_sector_reader.as_vector_of<sector_id>();
|
||||
|
||||
current_sector = current_sector_sectors.back();
|
||||
current_sector_sectors.pop_back();
|
||||
|
||||
master_sectors.insert(
|
||||
current_sector_sectors.begin(),
|
||||
current_sector_sectors.end(),
|
||||
master_sectors.end());
|
||||
}
|
||||
}
|
||||
|
||||
return master_sectors;
|
||||
}
|
||||
|
||||
byte_vector read_stream(const std::u16string &name) const
|
||||
std::vector<byte> read_stream(const std::u16string &name) const
|
||||
{
|
||||
const auto entry = directory_.entry(name);
|
||||
byte_vector result;
|
||||
|
||||
if (entry.size < header_.threshold())
|
||||
{
|
||||
result = load_short_sectors(short_sector_table_.follow(entry.first));
|
||||
result.resize(entry.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = load_sectors(sector_table_.follow(entry.first));
|
||||
result.resize(entry.size);
|
||||
}
|
||||
auto result = entry.size < header_.threshold()
|
||||
? read_short(short_sector_table_.follow(entry.first))
|
||||
: read(sector_table_.follow(entry.first));
|
||||
result.resize(entry.size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const byte *sectors_;
|
||||
const std::size_t sectors_size_;
|
||||
directory_tree directory_;
|
||||
header header_;
|
||||
allocation_table sector_table_;
|
||||
byte_vector sectors_;
|
||||
allocation_table short_sector_table_;
|
||||
byte_vector short_sectors_;
|
||||
std::vector<sector_id> short_container_stream_;
|
||||
};
|
||||
|
||||
class compound_document_writer_impl
|
||||
{
|
||||
public:
|
||||
compound_document_writer_impl(std::vector<std::uint8_t> &data)
|
||||
compound_document_writer_impl(std::vector<byte> &bytes)
|
||||
: writer_(bytes)
|
||||
{
|
||||
sector_table_.sector_size(header_.sector_size());
|
||||
short_sector_table_.sector_size(header_.short_sector_size());
|
||||
}
|
||||
|
||||
void write_sectors(const byte_vector &data, directory_entry &/*entry*/)
|
||||
void write_sectors(const std::vector<byte> &data, directory_entry &/*entry*/)
|
||||
{
|
||||
const auto sector_size = sector_table_.sector_size();
|
||||
const auto num_sectors = data.size() / sector_size;
|
||||
|
@ -732,11 +703,11 @@ public:
|
|||
{
|
||||
auto position = sector_size * i;
|
||||
auto current_sector_size = data.size() % sector_size;
|
||||
sectors_.append(data.data(), position, current_sector_size);
|
||||
writer_.append(data, position, current_sector_size);
|
||||
}
|
||||
}
|
||||
|
||||
void write_short_sectors(const byte_vector &data, directory_entry &/*entry*/)
|
||||
void write_short_sectors(const std::vector<byte> &data, directory_entry &/*entry*/)
|
||||
{
|
||||
const auto sector_size = sector_table_.sector_size();
|
||||
const auto num_sectors = data.size() / sector_size;
|
||||
|
@ -745,24 +716,11 @@ public:
|
|||
{
|
||||
auto position = sector_size * i;
|
||||
auto current_sector_size = data.size() % sector_size;
|
||||
sectors_.append(data.data(), position, current_sector_size);
|
||||
writer_.append(data, position, current_sector_size);
|
||||
}
|
||||
}
|
||||
|
||||
byte_vector save() const
|
||||
{
|
||||
auto result = byte_vector();
|
||||
|
||||
result.append(header_.save().data());
|
||||
result.append(sector_table_.save().data());
|
||||
result.append(short_sector_table_.save().data());
|
||||
result.append(directory_.save().data());
|
||||
result.append(sectors_.data());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void write_stream(const std::u16string &name, const byte_vector &data)
|
||||
void write_stream(const std::u16string &name, const std::vector<byte> &data)
|
||||
{
|
||||
auto &entry = directory_.entry(name, true);
|
||||
|
||||
|
@ -777,12 +735,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
binary_writer writer_;
|
||||
directory_tree directory_;
|
||||
header header_;
|
||||
allocation_table sector_table_;
|
||||
byte_vector sectors_;
|
||||
allocation_table short_sector_table_;
|
||||
byte_vector short_sectors_;
|
||||
std::vector<sector_id> short_container_stream_;
|
||||
};
|
||||
|
||||
|
@ -797,7 +754,7 @@ compound_document_reader::~compound_document_reader()
|
|||
|
||||
std::vector<std::uint8_t> compound_document_reader::read_stream(const std::u16string &name) const
|
||||
{
|
||||
return d_->read_stream(name).data();
|
||||
return d_->read_stream(name);
|
||||
}
|
||||
|
||||
compound_document_writer::compound_document_writer(std::vector<std::uint8_t> &data)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <detail/bytes.hpp>
|
||||
#include <detail/binary.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include <detail/bytes.hpp>
|
||||
#include <detail/binary.hpp>
|
||||
#include <detail/cryptography/aes.hpp>
|
||||
#include <detail/cryptography/encryption_info.hpp>
|
||||
|
||||
|
@ -37,7 +37,7 @@ std::vector<std::uint8_t> calculate_standard_key(
|
|||
{
|
||||
// H_0 = H(salt + password)
|
||||
auto salt_plus_password = info.salt;
|
||||
auto password_bytes = xlnt::detail::byte_vector::from(password).data();
|
||||
auto password_bytes = xlnt::detail::string_to_bytes(password);
|
||||
std::copy(password_bytes.begin(),
|
||||
password_bytes.end(),
|
||||
std::back_inserter(salt_plus_password));
|
||||
|
@ -107,7 +107,7 @@ std::vector<std::uint8_t> calculate_agile_key(
|
|||
{
|
||||
// H_0 = H(salt + password)
|
||||
auto salt_plus_password = info.key_encryptor.salt_value;
|
||||
auto password_bytes = xlnt::detail::byte_vector::from(password).data();
|
||||
auto password_bytes = xlnt::detail::string_to_bytes(password);
|
||||
std::copy(password_bytes.begin(),
|
||||
password_bytes.end(),
|
||||
std::back_inserter(salt_plus_password));
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <detail/bytes.hpp>
|
||||
#include <detail/binary.hpp>
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/unicode.hpp>
|
||||
#include <detail/cryptography/encryption_info.hpp>
|
||||
|
@ -42,7 +42,7 @@
|
|||
namespace {
|
||||
|
||||
using xlnt::detail::byte;
|
||||
using xlnt::detail::byte_vector;
|
||||
using xlnt::detail::binary_reader;
|
||||
using xlnt::detail::encryption_info;
|
||||
|
||||
std::vector<std::uint8_t> decrypt_xlsx_standard(
|
||||
|
@ -51,7 +51,7 @@ std::vector<std::uint8_t> decrypt_xlsx_standard(
|
|||
{
|
||||
const auto key = info.calculate_key();
|
||||
|
||||
auto reader = xlnt::detail::byte_reader(encrypted_package);
|
||||
auto reader = binary_reader(encrypted_package);
|
||||
auto decrypted_size = reader.read<std::uint64_t>();
|
||||
auto decrypted = xlnt::detail::aes_ecb_decrypt(encrypted_package, key, reader.offset());
|
||||
decrypted.resize(static_cast<std::size_t>(decrypted_size));
|
||||
|
@ -107,7 +107,7 @@ encryption_info::standard_encryption_info read_standard_encryption_info(const st
|
|||
{
|
||||
encryption_info::standard_encryption_info result;
|
||||
|
||||
auto reader = xlnt::detail::byte_reader(info_bytes);
|
||||
auto reader = binary_reader(info_bytes);
|
||||
|
||||
// skip version info
|
||||
reader.read<std::uint32_t>();
|
||||
|
@ -275,7 +275,7 @@ encryption_info read_encryption_info(const std::vector<std::uint8_t> &info_bytes
|
|||
|
||||
info.password = password;
|
||||
|
||||
auto reader = xlnt::detail::byte_reader(info_bytes);
|
||||
auto reader = binary_reader(info_bytes);
|
||||
|
||||
auto version_major = reader.read<std::uint16_t>();
|
||||
auto version_minor = reader.read<std::uint16_t>();
|
||||
|
|
|
@ -171,40 +171,41 @@ std::vector<std::uint8_t> write_agile_encryption_info(
|
|||
|
||||
std::vector<std::uint8_t> write_standard_encryption_info(const encryption_info &info)
|
||||
{
|
||||
xlnt::detail::byte_vector result;
|
||||
auto result = std::vector<std::uint8_t>();
|
||||
auto writer = xlnt::detail::binary_writer(result);
|
||||
|
||||
const auto version_major = std::uint16_t(4);
|
||||
const auto version_minor = std::uint16_t(2);
|
||||
const auto encryption_flags = std::uint32_t(0b00010000 & 0b00100000);
|
||||
|
||||
result.write(version_major);
|
||||
result.write(version_minor);
|
||||
result.write(encryption_flags);
|
||||
writer.write(version_major);
|
||||
writer.write(version_minor);
|
||||
writer.write(encryption_flags);
|
||||
|
||||
const auto header_length = std::uint32_t(32); // calculate this!
|
||||
|
||||
result.write(header_length);
|
||||
result.write(std::uint32_t(0)); // skip_flags
|
||||
result.write(std::uint32_t(0)); // size_extra
|
||||
result.write(std::uint32_t(0x0000660E));
|
||||
result.write(std::uint32_t(0x00008004));
|
||||
result.write(std::uint32_t(info.standard.key_bits));
|
||||
result.write(std::uint32_t(0x00000018));
|
||||
result.write(std::uint32_t(0));
|
||||
result.write(std::uint32_t(0));
|
||||
writer.write(header_length);
|
||||
writer.write(std::uint32_t(0)); // skip_flags
|
||||
writer.write(std::uint32_t(0)); // size_extra
|
||||
writer.write(std::uint32_t(0x0000660E));
|
||||
writer.write(std::uint32_t(0x00008004));
|
||||
writer.write(std::uint32_t(info.standard.key_bits));
|
||||
writer.write(std::uint32_t(0x00000018));
|
||||
writer.write(std::uint32_t(0));
|
||||
writer.write(std::uint32_t(0));
|
||||
|
||||
const auto provider = u"Microsoft Enhanced RSA and AES Cryptographic Provider";
|
||||
result.append(xlnt::detail::byte_vector::from(std::u16string(provider)).data());
|
||||
const auto provider = std::u16string(u"Microsoft Enhanced RSA and AES Cryptographic Provider");
|
||||
writer.append(xlnt::detail::string_to_bytes(provider));
|
||||
|
||||
result.write(std::uint32_t(info.standard.salt.size()));
|
||||
result.append(info.standard.salt);
|
||||
writer.write(std::uint32_t(info.standard.salt.size()));
|
||||
writer.append(info.standard.salt);
|
||||
|
||||
result.append(info.standard.encrypted_verifier);
|
||||
writer.append(info.standard.encrypted_verifier);
|
||||
|
||||
result.write(std::uint32_t(20));
|
||||
result.append(info.standard.encrypted_verifier_hash);
|
||||
writer.write(std::uint32_t(20));
|
||||
writer.append(info.standard.encrypted_verifier_hash);
|
||||
|
||||
return result.data();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> encrypt_xlsx_agile(
|
||||
|
|
Loading…
Reference in New Issue
Block a user