This commit is contained in:
ElenaSubbotina
2018-04-30 15:33:58 +03:00
parent 047850dbd6
commit 6bc04fc06f
5 changed files with 90 additions and 36 deletions

View File

@ -71,7 +71,7 @@ namespace odf_writer
{ {
CryptoPP::RandomPool prng; CryptoPP::RandomPool prng;
CryptoPP::SecByteBlock padding(780); CryptoPP::SecByteBlock padding(1024);
CryptoPP::OS_GenerateRandomBlock(false, padding, padding.size()); CryptoPP::OS_GenerateRandomBlock(false, padding, padding.size());
prng.IncorporateEntropy(padding, padding.size()); prng.IncorporateEntropy(padding, padding.size());
@ -299,6 +299,8 @@ namespace odf_writer
} }
void odf_document::write_manifest(const std::wstring & RootPath) void odf_document::write_manifest(const std::wstring & RootPath)
{ {
if (mimetype_)
mimetype_->write(RootPath);
if (manifest_) if (manifest_)
manifest_->write(RootPath); manifest_->write(RootPath);
} }

View File

@ -46,6 +46,11 @@ void relationship::serialize(std::wostream & _Wostream)
CP_XML_NODE(L"manifest:file-entry") CP_XML_NODE(L"manifest:file-entry")
{ {
CP_XML_ATTR(L"manifest:full-path", target_); CP_XML_ATTR(L"manifest:full-path", target_);
if (target_ == L"/")
{
CP_XML_ATTR(L"manifest:version", L"1.2");
}
CP_XML_ATTR(L"manifest:media-type", type_); CP_XML_ATTR(L"manifest:media-type", type_);
if (size_ >= 0) if (size_ >= 0)

View File

@ -86,8 +86,7 @@ void manifest_encryption_data::serialize(std::wostream & _Wostream)
{ {
CP_XML_NODE_SIMPLE() CP_XML_NODE_SIMPLE()
{ {
CP_XML_ATTR(L"manifest:checksum-type", L"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#" + CP_XML_ATTR(L"manifest:checksum-type", checksum_type_);
checksum_type_);
CP_XML_ATTR(L"manifest:checksum", checksum_); CP_XML_ATTR(L"manifest:checksum", checksum_);
if (algorithm_) algorithm_->serialize(CP_XML_STREAM()); if (algorithm_) algorithm_->serialize(CP_XML_STREAM());
@ -107,7 +106,7 @@ void manifest_algorithm::serialize(std::wostream & _Wostream)
{ {
CP_XML_NODE_SIMPLE() CP_XML_NODE_SIMPLE()
{ {
CP_XML_ATTR(L"manifest:algorithm-name", L"http://www.w3.org/2001/04/xmlenc#" + algorithm_name_); CP_XML_ATTR(L"manifest:algorithm-name", algorithm_name_);
CP_XML_ATTR(L"manifest:initialisation-vector", initialisation_vector_); CP_XML_ATTR(L"manifest:initialisation-vector", initialisation_vector_);
} }
} }
@ -142,8 +141,7 @@ void manifest_start_key_generation::serialize(std::wostream & _Wostream)
{ {
CP_XML_NODE_SIMPLE() CP_XML_NODE_SIMPLE()
{ {
CP_XML_ATTR(L"manifest:start-key-generation-name", L"http://www.w3.org/2000/09/xmldsig#" + CP_XML_ATTR(L"manifest:start-key-generation-name", start_key_generation_name_);
start_key_generation_name_);
CP_XML_ATTR(L"manifest:key-size", key_size_); CP_XML_ATTR(L"manifest:key-size", key_size_);
} }
} }

View File

@ -64,6 +64,7 @@
#include "../../../Common/DocxFormat/Source/XlsxFormat/Worksheets/Sparkline.h" #include "../../../Common/DocxFormat/Source/XlsxFormat/Worksheets/Sparkline.h"
#include "../../../OfficeCryptReader/source/CryptTransform.h" #include "../../../OfficeCryptReader/source/CryptTransform.h"
#include "../../../DesktopEditor/common/Directory.h"
#define PROGRESSEVENT_ID 0 #define PROGRESSEVENT_ID 0
@ -176,6 +177,19 @@ bool OoxConverter::encrypt_document (const std::wstring &password, const std::ws
std::wstring inp_file_name = srcPath + FILE_SEPARATOR_STR + rels->relationships_[i].target_; std::wstring inp_file_name = srcPath + FILE_SEPARATOR_STR + rels->relationships_[i].target_;
std::wstring out_file_name = dstPath + FILE_SEPARATOR_STR + rels->relationships_[i].target_; std::wstring out_file_name = dstPath + FILE_SEPARATOR_STR + rels->relationships_[i].target_;
if (std::wstring::npos != rels->relationships_[i].target_.find(L"/"))
{
std::vector<std::wstring> refs;
boost::algorithm::split(refs, rels->relationships_[i].target_, boost::algorithm::is_any_of(L"/"), boost::algorithm::token_compress_on);
std::wstring folder = dstPath;
for (size_t j = 0; j < refs.size() - 1; j++)
{
folder += FILE_SEPARATOR_STR + refs[j];
NSDirectory::CreateDirectory(folder);
}
}
encrypt_file(password, inp_file_name, out_file_name, rels->relationships_[i].encryption_, rels->relationships_[i].size_); encrypt_file(password, inp_file_name, out_file_name, rels->relationships_[i].encryption_, rels->relationships_[i].size_);
} }
} }
@ -183,7 +197,9 @@ bool OoxConverter::encrypt_file (const std::wstring &password, const std::wstrin
{ {
CRYPT::ODFEncryptor encryptor; CRYPT::ODFEncryptor encryptor;
CRYPT::_odfCryptData cryptData; CRYPT::_odfCryptData cryptData;
//-----------------------
//aes
cryptData.cipherAlgorithm = CRYPT_METHOD::AES_CBC;
cryptData.start_hashAlgorithm = CRYPT_METHOD::SHA256; cryptData.start_hashAlgorithm = CRYPT_METHOD::SHA256;
cryptData.start_hashSize = 32; cryptData.start_hashSize = 32;
@ -192,7 +208,18 @@ bool OoxConverter::encrypt_file (const std::wstring &password, const std::wstrin
cryptData.checksum_size = 1024; cryptData.checksum_size = 1024;
cryptData.checksum_hashAlgorithm = CRYPT_METHOD::SHA256; cryptData.checksum_hashAlgorithm = CRYPT_METHOD::SHA256;
//-----------------------
//blowfish
//cryptData.cipherAlgorithm = CRYPT_METHOD::Blowfish_CFB;
//cryptData.start_hashAlgorithm = CRYPT_METHOD::SHA1;
//cryptData.start_hashSize = 20;
//cryptData.spinCount = 1024;
//cryptData.keySize = 16;
//cryptData.checksum_size = 1024;
//cryptData.checksum_hashAlgorithm = CRYPT_METHOD::SHA1;
//-----------------------
NSFile::CFileBinary file; NSFile::CFileBinary file;
if (false == file.OpenFile(srcPath)) if (false == file.OpenFile(srcPath))
@ -248,8 +275,9 @@ bool OoxConverter::encrypt_file (const std::wstring &password, const std::wstrin
{ {
switch(cryptData.start_hashAlgorithm) switch(cryptData.start_hashAlgorithm)
{ {
case CRYPT_METHOD::SHA256: start_key_generation->start_key_generation_name_ = L"sha256"; break; case CRYPT_METHOD::SHA1: start_key_generation->start_key_generation_name_ = L"SHA1"; break;
case CRYPT_METHOD::SHA512: start_key_generation->start_key_generation_name_ = L"sha512"; break; case CRYPT_METHOD::SHA256: start_key_generation->start_key_generation_name_ = L"http://www.w3.org/2000/09/xmldsig#sha256"; break;
case CRYPT_METHOD::SHA512: start_key_generation->start_key_generation_name_ = L"http://www.w3.org/2000/09/xmldsig#sha512"; break;
} }
start_key_generation->key_size_ = cryptData.start_hashSize; start_key_generation->key_size_ = cryptData.start_hashSize;
} }
@ -260,8 +288,8 @@ bool OoxConverter::encrypt_file (const std::wstring &password, const std::wstrin
switch(cryptData.cipherAlgorithm) switch(cryptData.cipherAlgorithm)
{ {
case CRYPT_METHOD::AES_CBC: algorithm->algorithm_name_ = L"aes256-cbc"; break; case CRYPT_METHOD::AES_CBC: algorithm->algorithm_name_ = L"http://www.w3.org/2001/04/xmlenc#aes256-cbc"; break;
case CRYPT_METHOD::Blowfish_CFB: algorithm->algorithm_name_ = L"Blowfish"; break; case CRYPT_METHOD::Blowfish_CFB: algorithm->algorithm_name_ = L"Blowfish CFB"; break;
} }
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -271,11 +299,17 @@ bool OoxConverter::encrypt_file (const std::wstring &password, const std::wstrin
switch(cryptData.checksum_hashAlgorithm) switch(cryptData.checksum_hashAlgorithm)
{ {
case CRYPT_METHOD::SHA256: encryption_data->checksum_type_ = L"sha256"; break; case CRYPT_METHOD::SHA1: encryption_data->checksum_type_ = L"SHA1"; break;
case CRYPT_METHOD::SHA512: encryption_data->checksum_type_ = L"sha512"; break; case CRYPT_METHOD::SHA256: encryption_data->checksum_type_ = L"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#sha256"; break;
case CRYPT_METHOD::SHA512: encryption_data->checksum_type_ = L"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#sha512"; break;
} }
if (cryptData.checksum_size == 1024) if (cryptData.checksum_size == 1024)
encryption_data->checksum_type_ += L"-1k"; {
if (cryptData.checksum_hashAlgorithm == CRYPT_METHOD::SHA1)
encryption_data->checksum_type_ += L"/1K";
else
encryption_data->checksum_type_ += L"-1k";
}
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
std::wstringstream strm; std::wstringstream strm;

View File

@ -369,6 +369,11 @@ bool EncryptCipher(_buf & key, _buf & iv, _buf & data_inp, _buf & data_out, CRYP
rc4Encryption.ProcessData(data_out.ptr, data_inp.ptr, data_inp.size); rc4Encryption.ProcessData(data_out.ptr, data_inp.ptr, data_inp.size);
} }
else if (algorithm == CRYPT_METHOD::Blowfish_CFB)
{
CFB_Mode<Blowfish>::Encryption encryption(key.ptr, key.size, iv.ptr);
encryption.ProcessData(data_out.ptr, data_inp.ptr, data_inp.size);
}
else //AES else //AES
{ {
StreamTransformation *modeEncryption = NULL; StreamTransformation *modeEncryption = NULL;
@ -759,9 +764,9 @@ void ECMAEncryptor::SetPassword(std::wstring _password)
_buf pInputBlockKey ((unsigned char*)encrVerifierHashInputBlockKey, 8); _buf pInputBlockKey ((unsigned char*)encrVerifierHashInputBlockKey, 8);
_buf pValueBlockKey ((unsigned char*)encrVerifierHashValueBlockKey, 8); _buf pValueBlockKey ((unsigned char*)encrVerifierHashValueBlockKey, 8);
_buf pSalt (seed_salt.m_ptr, seed_salt.m_size); _buf pSalt (seed_salt.data(), seed_salt.size());
_buf pDataSalt (seed_datasalt.m_ptr, seed_datasalt.m_size); _buf pDataSalt (seed_datasalt.data(), seed_datasalt.size());
_buf pDecryptedKey (seed_key.m_ptr, seed_key.m_size); _buf pDecryptedKey (seed_key.data(), seed_key.size());
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
_buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); _buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm);
@ -770,7 +775,7 @@ void ECMAEncryptor::SetPassword(std::wstring _password)
EncryptCipher( agileKey, pSalt, pDecryptedKey, pKeyValue, cryptData.cipherAlgorithm); EncryptCipher( agileKey, pSalt, pDecryptedKey, pKeyValue, cryptData.cipherAlgorithm);
//-------------------------------------------- //--------------------------------------------
_buf decryptedVerifierHashInputBytes(seed_verify.m_ptr, seed_verify.m_size); _buf decryptedVerifierHashInputBytes(seed_verify.data(), seed_verify.size());
_buf verifierInputKey = GenerateAgileKey( pSalt, pPassword, pInputBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm ); _buf verifierInputKey = GenerateAgileKey( pSalt, pPassword, pInputBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm );
_buf pEncVerInput; _buf pEncVerInput;
@ -834,7 +839,7 @@ void ECMAEncryptor::UpdateDataIntegrity(unsigned char* data, int size)
CryptoPP::OS_GenerateRandomBlock(false, seed, seed.size()); CryptoPP::OS_GenerateRandomBlock(false, seed, seed.size());
prng.IncorporateEntropy(seed, seed.size()); prng.IncorporateEntropy(seed, seed.size());
_buf pSaltHmac(seed.m_ptr, seed.m_size); _buf pSaltHmac(seed.data(), seed.size());
std::string sData((char*)data, size); std::string sData((char*)data, size);
_buf hmac = Hmac(pSaltHmac, cryptData.hashAlgorithm, sData); _buf hmac = Hmac(pSaltHmac, cryptData.hashAlgorithm, sData);
@ -876,16 +881,9 @@ int ECMAEncryptor::Encrypt(unsigned char* data_inp_ptr, int size, unsigned char*
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
_buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); _buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm);
//тут нужно именно дешифрованый генерить - пока их файла берем
_buf pDecryptedKey; _buf pDecryptedKey;
DecryptCipher( agileKey, pSalt, pKeyValue, pDecryptedKey, cryptData.cipherAlgorithm); DecryptCipher( agileKey, pSalt, pKeyValue, pDecryptedKey, cryptData.cipherAlgorithm);
////зашифровать ключь
//_buf pEncryptedKey;
//EncryptCipher( agileKey, pSalt, pDecryptedKey, pEncryptedKey, cryptData.cipherAlgorithm);
////??? pEncryptedKey == pKeyValue;
//------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------
_buf iv(cryptData.blockSize, true); _buf iv(cryptData.blockSize, true);
@ -960,8 +958,18 @@ bool ODFDecryptor::Decrypt(const std::wstring & wspassword, unsigned char* data_
_buf pInp(data_inp, size_inp, false); _buf pInp(data_inp, size_inp, false);
_buf pOut(size_inp); _buf pOut(size_inp);
if (false == DecryptCipher(pKey, ivi, pInp, pOut, cryptData.cipherAlgorithm)) bool bPadding = false;
if ((cryptData.cipherAlgorithm == CRYPT_METHOD::AES_CBC) && (size_inp % PADDING_SIZE != 0))
{
bPadding = true;
}
if (false == DecryptCipher(pKey, ivi, pInp, pOut, cryptData.cipherAlgorithm, bPadding ? StreamTransformationFilter::ONE_AND_ZEROS_PADDING :
StreamTransformationFilter::NO_PADDING))
{
return false; return false;
}
_buf pChecksum (cryptData.checksum); _buf pChecksum (cryptData.checksum);
@ -973,9 +981,9 @@ bool ODFDecryptor::Decrypt(const std::wstring & wspassword, unsigned char* data_
{ {
if (bVerify) if (bVerify)
{ {
data_out = new unsigned char[size_out]; data_out = new unsigned char[size_out + 1024];
Inflator inflator(new ArraySink(data_out, size_out)); Inflator inflator(new ArraySink(data_out, size_out + 1024));
inflator.Put(pOut.ptr, pOut.size); inflator.Put(pOut.ptr, pOut.size);
inflator.MessageEnd(); inflator.MessageEnd();
@ -1005,15 +1013,15 @@ int ODFEncryptor::Encrypt (const std::wstring & wspassword, unsigned char* data,
cryptData.saltValue = std::string((char*)seed_salt.data(), seed_salt.size()); cryptData.saltValue = std::string((char*)seed_salt.data(), seed_salt.size());
//сгенерить стартовый //сгенерить стартовый
CryptoPP::SecByteBlock start_vector(cryptData.start_hashSize); CryptoPP::SecByteBlock start_vector(16);
CryptoPP::OS_GenerateRandomBlock(false, start_vector, start_vector.size()); CryptoPP::OS_GenerateRandomBlock(false, start_vector, start_vector.size());
prng.IncorporateEntropy(start_vector, start_vector.size()); prng.IncorporateEntropy(start_vector, start_vector.size());
cryptData.initializationVector = std::string((char*)start_vector.data(), start_vector.size()); cryptData.initializationVector = std::string((char*)start_vector.data(), start_vector.size());
//-------- //-------------------------------------
_buf data_deflate(size); _buf data_deflate(size + 1024);
ArraySink *sink = new ArraySink(data_deflate.ptr, data_deflate.size); ArraySink *sink = new ArraySink(data_deflate.ptr, data_deflate.size + 1024);
Deflator deflator(sink); Deflator deflator(sink);
@ -1034,14 +1042,21 @@ int ODFEncryptor::Encrypt (const std::wstring & wspassword, unsigned char* data,
//--------- //---------
int size_out = data_deflate.size; int size_out = data_deflate.size;
bool bPadding = (cryptData.cipherAlgorithm == CRYPT_METHOD::AES_CBC);
if (bPadding && (size_out % PADDING_SIZE != 0))
size_out = (size_out / PADDING_SIZE + 1) * PADDING_SIZE;
data_out = new unsigned char[size_out]; data_out = new unsigned char[size_out];
_buf pOut (data_out, size_out, false); _buf pOut (data_out, size_out, false);
_buf pKey = GenerateOdfKey(pSalt, pPassword, cryptData.keySize, cryptData.spinCount, cryptData.start_hashAlgorithm); _buf pKey = GenerateOdfKey(pSalt, pPassword, cryptData.keySize, cryptData.spinCount, cryptData.start_hashAlgorithm);
EncryptCipher(pKey, ivi, data_deflate, pOut, cryptData.cipherAlgorithm); EncryptCipher(pKey, ivi, data_deflate, pOut, cryptData.cipherAlgorithm, bPadding ? StreamTransformationFilter::ONE_AND_ZEROS_PADDING :
StreamTransformationFilter::NO_PADDING);
return size_out; return pOut.size;
} }
void ODFEncryptor::SetCryptData(_odfCryptData &data) void ODFEncryptor::SetCryptData(_odfCryptData &data)