Kaydet (Commit) 13aedd1d authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

Save should encrypt OOXML document if it was loaded encrypted.

Currently Agile encryption is not supported, so all documents
loaded with "agile" encryption will be encrypted with "standard"
encryption when they are saved afterwards.

Change-Id: Id0477f43c00ed70032ca6b3390eebb1105d5ffa7
üst e0a43dff
......@@ -59,7 +59,7 @@ public:
bool readEncryptionInfo();
bool generateEncryptionKey(const OUString& rPassword);
com::sun::star::uno::Sequence< com::sun::star::beans::NamedValue > createEncryptionData();
com::sun::star::uno::Sequence< com::sun::star::beans::NamedValue > createEncryptionData(const OUString& rPassword);
static bool checkEncryptionData( const com::sun::star::uno::Sequence< com::sun::star::beans::NamedValue >& rEncryptionData );
};
......
......@@ -89,11 +89,6 @@ public:
StandardEncryptionInfo& getInfo();
static bool checkEncryptionData(
std::vector<sal_uInt8> key, sal_uInt32 keySize,
std::vector<sal_uInt8> encryptedVerifier, sal_uInt32 verifierSize,
std::vector<sal_uInt8> encryptedHash, sal_uInt32 hashSize );
virtual bool generateEncryptionKey(const OUString& rPassword);
virtual bool writeEncryptionInfo(
......
......@@ -545,7 +545,8 @@ void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDesc
OUString sFilterName = mxImpl->maMediaDesc.getUnpackedValueOrDefault( "FilterName", OUString() );
try
{
Reference< XNameAccess > xFilters( Reference<XMultiServiceFactory>(getComponentContext()->getServiceManager(), UNO_QUERY_THROW)->createInstance("com.sun.star.document.FilterFactory" ), UNO_QUERY_THROW );
Reference<XMultiServiceFactory> xFactory(getComponentContext()->getServiceManager(), UNO_QUERY_THROW);
Reference<XNameAccess> xFilters(xFactory->createInstance("com.sun.star.document.FilterFactory" ), UNO_QUERY_THROW );
Any aValues = xFilters->getByName( sFilterName );
Sequence<PropertyValue > aPropSeq;
aValues >>= aPropSeq;
......
......@@ -286,8 +286,8 @@ PasswordVerifier::PasswordVerifier( DocumentDecryption& aDecryptor ) :
comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword, Sequence<NamedValue>& rEncryptionData )
{
if( mDecryptor.generateEncryptionKey(rPassword) )
rEncryptionData = mDecryptor.createEncryptionData();
if(mDecryptor.generateEncryptionKey(rPassword))
rEncryptionData = mDecryptor.createEncryptionData(rPassword);
return rEncryptionData.hasElements() ? comphelper::DocPasswordVerifierResult_OK : comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
}
......
......@@ -657,7 +657,7 @@ Reference<XStream> XmlFilterBase::implGetOutputStream( MediaDescriptor& rMediaDe
OUString aPassword;
for (int i=0; i<aMediaEncData.getLength(); i++)
{
if (aMediaEncData[i].Name == "Password")
if (aMediaEncData[i].Name == "OOXPassword")
{
Any& any = aMediaEncData[i].Value;
any >>= aPassword;
......@@ -690,7 +690,7 @@ bool XmlFilterBase::implFinalizeExport( MediaDescriptor& rMediaDescriptor )
for (int i=0; i<aMediaEncData.getLength(); i++)
{
if (aMediaEncData[i].Name == "Password")
if (aMediaEncData[i].Name == "OOXPassword")
{
Any& any = aMediaEncData[i].Value;
any >>= aPassword;
......
......@@ -202,23 +202,9 @@ DocumentDecryption::DocumentDecryption(oox::ole::OleStorage& rOleStorage, Refere
mCryptoType(UNKNOWN)
{}
bool DocumentDecryption::checkEncryptionData(const Sequence<NamedValue>& rEncryptionData)
bool DocumentDecryption::checkEncryptionData(const Sequence<NamedValue>& /*rEncryptionData*/)
{
SequenceAsHashMap aHashData( rEncryptionData );
OUString type = aHashData.getUnpackedValueOrDefault( "CryptoType", OUString("Unknown") );
if (type == "Standard")
{
Sequence<sal_Int8> aKeySeq = aHashData.getUnpackedValueOrDefault( "AES128EncryptionKey", Sequence<sal_Int8>() );
Sequence<sal_Int8> aVerifierSeq = aHashData.getUnpackedValueOrDefault( "AES128EncryptionVerifier", Sequence<sal_Int8>() );
Sequence<sal_Int8> aHashSeq = aHashData.getUnpackedValueOrDefault( "AES128EncryptionVerifierHash", Sequence<sal_Int8>() );
vector<sal_uInt8> key = convertToVector(aKeySeq);
vector<sal_uInt8> verifier = convertToVector(aVerifierSeq);
vector<sal_uInt8> hash = convertToVector(aHashSeq);
return Standard2007Engine::checkEncryptionData( key, key.size(), verifier, verifier.size(), hash, hash.size() );
}
return type == "Agile";
return false;
}
bool DocumentDecryption::generateEncryptionKey(const OUString& rPassword)
......@@ -363,30 +349,21 @@ bool DocumentDecryption::readEncryptionInfo()
return bResult;
}
Sequence<NamedValue> DocumentDecryption::createEncryptionData()
Sequence<NamedValue> DocumentDecryption::createEncryptionData(const OUString& rPassword)
{
Sequence<NamedValue> aResult;
vector<sal_uInt8>& key = mEngine->getKey();
SequenceAsHashMap aEncryptionData;
if (key.size() > 0)
if (mCryptoType == AGILE)
{
SequenceAsHashMap aEncryptionData;
if (mCryptoType == AGILE)
{
aEncryptionData["CryptoType"] <<= OUString("Agile");
aEncryptionData["AES128EncryptionKey"] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( &key[0] ), key.size() );
aResult = aEncryptionData.getAsConstNamedValueList();
}
else if (mCryptoType == STANDARD_2007)
{
aEncryptionData["CryptoType"] <<= OUString("Standard");
aEncryptionData["AES128EncryptionKey"] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( &key[0] ), key.size() );
aResult = aEncryptionData.getAsConstNamedValueList();
}
aEncryptionData["CryptoType"] <<= OUString("Agile");
}
else if (mCryptoType == STANDARD_2007)
{
aEncryptionData["CryptoType"] <<= OUString("Standard");
}
return aResult;
aEncryptionData["OOXPassword"] <<= rPassword;
return aEncryptionData.getAsConstNamedValueList();
}
bool DocumentDecryption::decrypt(Reference<XStream> xDocumentStream)
......
......@@ -164,16 +164,22 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password)
mInfo.verifier.encryptedVerifier + ENCRYPTED_VERIFIER_LENGTH,
encryptedVerifier.begin());
vector<sal_uInt8> encryptedVerifierHash(ENCRYPTED_VERIFIER_HASH_LENGTH);
vector<sal_uInt8> encryptedHash(ENCRYPTED_VERIFIER_HASH_LENGTH);
std::copy(
mInfo.verifier.encryptedVerifierHash,
mInfo.verifier.encryptedVerifierHash + ENCRYPTED_VERIFIER_HASH_LENGTH,
encryptedVerifierHash.begin());
encryptedHash.begin());
return checkEncryptionData(
mKey, mKey.size(),
encryptedVerifier, encryptedVerifier.size(),
encryptedVerifierHash, encryptedVerifierHash.size() );
vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
Decrypt::aes128ecb(verifier, encryptedVerifier, mKey);
vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
Decrypt::aes128ecb(verifierHash, encryptedHash, mKey);
vector<sal_uInt8> hash(RTL_DIGEST_LENGTH_SHA1, 0);
sha1(hash, verifier);
return std::equal( hash.begin(), hash.end(), verifierHash.begin() );
}
bool Standard2007Engine::decrypt(
......@@ -199,27 +205,6 @@ bool Standard2007Engine::decrypt(
return true;
}
bool Standard2007Engine::checkEncryptionData(
vector<sal_uInt8> key, sal_uInt32 keySize,
vector<sal_uInt8> encryptedVerifier, sal_uInt32 verifierSize,
vector<sal_uInt8> encryptedHash, sal_uInt32 hashSize )
{
// the only currently supported algorithm needs key size 128
if ( keySize != 16 || verifierSize != 16 )
return false;
vector<sal_uInt8> verifier(verifierSize, 0);
Decrypt::aes128ecb(verifier, encryptedVerifier, key);
vector<sal_uInt8> verifierHash(hashSize, 0);
Decrypt::aes128ecb(verifierHash, encryptedHash, key);
vector<sal_uInt8> hash(RTL_DIGEST_LENGTH_SHA1, 0);
sha1(hash, verifier);
return std::equal( hash.begin(), hash.end(), verifierHash.begin() );
}
bool Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOutputStream& rStream)
{
mInfo.header.flags = ENCRYPTINFO_AES | ENCRYPTINFO_CRYPTOAPI;
......
......@@ -2625,7 +2625,7 @@ ErrCode RequestPassword(const SfxFilter* pCurrentFilter, OUString& aURL, SfxItem
if ( lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName() ) )
{
::comphelper::SequenceAsHashMap aHashData;
aHashData[ OUString( "Password" ) ] <<= pPasswordRequest->getPassword();
aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword();
pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
}
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment