mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
.
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
@ -175,6 +176,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;
|
||||||
|
|||||||
@ -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, bPadding ? StreamTransformationFilter::ONE_AND_ZEROS_PADDING :
|
||||||
|
StreamTransformationFilter::NO_PADDING);
|
||||||
|
|
||||||
EncryptCipher(pKey, ivi, data_deflate, pOut, cryptData.cipherAlgorithm);
|
return pOut.size;
|
||||||
|
|
||||||
return size_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODFEncryptor::SetCryptData(_odfCryptData &data)
|
void ODFEncryptor::SetCryptData(_odfCryptData &data)
|
||||||
|
|||||||
Reference in New Issue
Block a user