1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Adds PCK encryption support (using script encryption key for export).

Change default encryption mode from ECB to CFB.
This commit is contained in:
bruvzg
2020-04-28 20:51:29 +03:00
parent 52f6ac81be
commit f043eabdd8
18 changed files with 692 additions and 151 deletions

View File

@@ -30,6 +30,8 @@
#include "file_access_pack.h"
#include "core/io/file_access_encrypted.h"
#include "core/script_language.h"
#include "core/version.h"
#include <stdio.h>
@@ -44,13 +46,14 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_
return ERR_FILE_UNRECOGNIZED;
}
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) {
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) {
PathMD5 pmd5(path.md5_buffer());
//printf("adding path %s, %lli, %lli\n", path.utf8().get_data(), pmd5.a, pmd5.b);
bool exists = files.has(pmd5);
PackedFile pf;
pf.encrypted = p_encrypted;
pf.pack = pkg_path;
pf.offset = ofs;
pf.size = size;
@@ -179,6 +182,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
}
uint32_t pack_flags = f->get_32();
uint64_t file_base = f->get_64();
bool enc_directory = (pack_flags & PACK_DIR_ENCRYPTED);
for (int i = 0; i < 16; i++) {
//reserved
f->get_32();
@@ -186,6 +194,30 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
int file_count = f->get_32();
if (enc_directory) {
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
if (!fae) {
f->close();
memdelete(f);
ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
}
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < key.size(); i++) {
key.write[i] = script_encryption_key[i];
}
Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
if (err) {
f->close();
memdelete(f);
memdelete(fae);
ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
}
f = fae;
}
for (int i = 0; i < file_count; i++) {
uint32_t sl = f->get_32();
CharString cs;
@@ -196,11 +228,13 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
String path;
path.parse_utf8(cs.ptr());
uint64_t ofs = f->get_64();
uint64_t ofs = file_base + f->get_64();
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files);
uint32_t flags = f->get_32();
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED));
}
f->close();
@@ -234,7 +268,7 @@ void FileAccessPack::seek(size_t p_position) {
eof = false;
}
f->seek(pf.offset + p_position);
f->seek(off + p_position);
pos = p_position;
}
@@ -319,12 +353,35 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
f->seek(pf.offset);
off = pf.offset;
if (pf.encrypted) {
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
if (!fae) {
ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
}
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < key.size(); i++) {
key.write[i] = script_encryption_key[i];
}
Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
if (err) {
memdelete(fae);
ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
}
f = fae;
off = 0;
}
pos = 0;
eof = false;
}
FileAccessPack::~FileAccessPack() {
if (f) {
f->close();
memdelete(f);
}
}