diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-12-10 23:40:00 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-01-13 14:17:48 +0100 |
commit | 01c7a60c051ac4562e3a317dde3c29c507f3f40b (patch) | |
tree | 0b7104b75ba3910ed0363b46bc66b4b5afaede3e /package | |
parent | 3271e8b90f5d522fdfe1de46b77e7f67cdaa75af (diff) |
tdf#114550: load back PGP encrypted files
This squashes the following commits from master:
gpg4libre: import PGP encryption manifest
Change-Id: Iadd7f8f1194299cb50907d8594114c89c668ebd0
gpg4libre: open encrypted files also via gpg
Change-Id: I1f626143e6c8443b4ad0c4fc5bdbd5ab8d56a451
tdf#114550 use 32 bit random session key for gpg encryption
Change-Id: I7303be71fd855aa454d07fcae04d7f42e3c9cd9c
tdf#114550 recognize sym key & init vec as valid f/ decrypt
Change-Id: Ie366f086a3c14d6b54b91b4edee8cfef1a42c44b
tdf#114550 don't use PBKDF2 in package for gpg encryption
Change-Id: Ic96b2193f8541bbd109795fb9c0212a0a10c7344
gpg4libre: add initial unit test for encryption
Change-Id: Id782dd865878ae7b8a60c7c80821b1370f6ac7e7
Change-Id: Id77b67a275bf91614ab62b65fdc69e4872247ffc
Reviewed-on: https://gerrit.libreoffice.org/47784
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'package')
-rw-r--r-- | package/inc/ZipPackageEntry.hxx | 1 | ||||
-rw-r--r-- | package/inc/ZipPackageFolder.hxx | 2 | ||||
-rw-r--r-- | package/inc/ZipPackageStream.hxx | 1 | ||||
-rw-r--r-- | package/source/manifest/ManifestImport.cxx | 172 | ||||
-rw-r--r-- | package/source/manifest/ManifestImport.hxx | 25 | ||||
-rw-r--r-- | package/source/xstor/xstorage.cxx | 4 | ||||
-rw-r--r-- | package/source/zipapi/XUnbufferedStream.cxx | 5 | ||||
-rw-r--r-- | package/source/zipapi/ZipFile.cxx | 9 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 62 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageFolder.cxx | 10 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackageStream.cxx | 3 |
11 files changed, 280 insertions, 14 deletions
diff --git a/package/inc/ZipPackageEntry.hxx b/package/inc/ZipPackageEntry.hxx index 300b5f25ea67..5e0064f9bf7e 100644 --- a/package/inc/ZipPackageEntry.hxx +++ b/package/inc/ZipPackageEntry.hxx @@ -69,6 +69,7 @@ public: std::vector < css::uno::Sequence < css::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const css::uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool ) = 0; void clearParent() diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx index 0fad51f72ba2..1f65b2ca297e 100644 --- a/package/inc/ZipPackageFolder.hxx +++ b/package/inc/ZipPackageFolder.hxx @@ -73,6 +73,7 @@ public: std::vector < css::uno::Sequence < css::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const css::uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool ) override; // Recursive functions @@ -82,6 +83,7 @@ public: std::vector < css::uno::Sequence < css::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const css::uno::Sequence< sal_Int8 > &rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool & rRandomPool) const; // XNameContainer diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx index d8f6903e35ac..cf8129e8d0a2 100644 --- a/package/inc/ZipPackageStream.hxx +++ b/package/inc/ZipPackageStream.hxx @@ -132,6 +132,7 @@ public: std::vector < css::uno::Sequence < css::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const css::uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool ) override; void setZipEntryOnLoading( const ZipEntry &rInEntry); diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx index 5ecd8c1cffcd..98a9d61128b5 100644 --- a/package/source/manifest/ManifestImport.cxx +++ b/package/source/manifest/ManifestImport.cxx @@ -34,6 +34,7 @@ using namespace std; ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector ) : bIgnoreEncryptData ( false ) + , bPgpEncryption ( false ) , nDerivedKeySize( 0 ) , rManVector ( rNewManVector ) @@ -57,6 +58,17 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV , sChecksumAttribute ( ATTRIBUTE_CHECKSUM ) , sChecksumTypeAttribute ( ATTRIBUTE_CHECKSUM_TYPE ) + , sKeyInfoElement ( ELEMENT_ENCRYPTED_KEYINFO ) + , sManifestKeyInfoElement ( ELEMENT_MANIFEST_KEYINFO ) + , sEncryptedKeyElement ( ELEMENT_ENCRYPTEDKEY ) + , sEncryptionMethodElement ( ELEMENT_ENCRYPTIONMETHOD ) + , sPgpDataElement ( ELEMENT_PGPDATA ) + , sPgpKeyIDElement ( ELEMENT_PGPKEYID ) + , sPGPKeyPacketElement ( ELEMENT_PGPKEYPACKET ) + , sAlgorithmAttribute ( ATTRIBUTE_ALGORITHM ) + , sCipherDataElement ( ELEMENT_CIPHERDATA ) + , sCipherValueElement ( ELEMENT_CIPHERVALUE ) + , sFullPathProperty ( "FullPath" ) , sMediaTypeProperty ( "MediaType" ) , sVersionProperty ( "Version" ) @@ -126,6 +138,80 @@ void ManifestImport::doFileEntry(StringHashMap &rConvertedAttribs) } } +void ManifestImport::doKeyInfoEntry(StringHashMap &) +{ +} + +void ManifestImport::doEncryptedKey(StringHashMap &) +{ + aKeyInfoSequence.clear(); + aKeyInfoSequence.resize(3); +} + +void ManifestImport::doEncryptionMethod(StringHashMap &rConvertedAttribs) +{ + OUString aString = rConvertedAttribs[sAlgorithmAttribute]; + if ( aKeyInfoSequence.size() != 3 + || aString != "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" ) + { + bIgnoreEncryptData = true; + } +} + +void ManifestImport::doEncryptedKeyInfo(StringHashMap &) +{ +} + +void ManifestImport::doEncryptedCipherData(StringHashMap &) +{ +} + +void ManifestImport::doEncryptedPgpData(StringHashMap &) +{ +} + +void ManifestImport::doEncryptedCipherValue() +{ + if ( aKeyInfoSequence.size() == 3 ) + { + aKeyInfoSequence[2].Name = "CipherValue"; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters); + aKeyInfoSequence[2].Value <<= aDecodeBuffer; + aCurrentCharacters = ""; // consumed + } + else + bIgnoreEncryptData = true; +} + +void ManifestImport::doEncryptedKeyId() +{ + if ( aKeyInfoSequence.size() == 3 ) + { + aKeyInfoSequence[0].Name = "KeyId"; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters); + aKeyInfoSequence[0].Value <<= aDecodeBuffer; + aCurrentCharacters = ""; // consumed + } + else + bIgnoreEncryptData = true; +} + +void ManifestImport::doEncryptedKeyPacket() +{ + if ( aKeyInfoSequence.size() == 3 ) + { + aKeyInfoSequence[1].Name = "KeyPacket"; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters); + aKeyInfoSequence[1].Value <<= aDecodeBuffer; + aCurrentCharacters = ""; // consumed + } + else + bIgnoreEncryptData = true; +} + void ManifestImport::doEncryptionData(StringHashMap &rConvertedAttribs) { // If this element exists, then this stream is encrypted and we need @@ -214,6 +300,9 @@ void ManifestImport::doKeyDerivation(StringHashMap &rConvertedAttribs) aSequence[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty; aSequence[PKG_MNFST_DERKEYSIZE].Value <<= nDerivedKeySize; + } else if ( bPgpEncryption ) { + if ( aString != "PGP" ) + bIgnoreEncryptData = true; } else bIgnoreEncryptData = true; } @@ -250,6 +339,8 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re case 2: { if (aConvertedName == sFileEntryElement) //manifest:file-entry doFileEntry(aConvertedAttribs); + else if (aConvertedName == sManifestKeyInfoElement) //loext:KeyInfo + doKeyInfoEntry(aConvertedAttribs); else aStack.back().m_bValid = false; break; @@ -262,6 +353,8 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re aStack.back().m_bValid = false; else if (aConvertedName == sEncryptionDataElement) //manifest:encryption-data doEncryptionData(aConvertedAttribs); + else if (aConvertedName == sEncryptedKeyElement) //loext:encrypted-key + doEncryptedKey(aConvertedAttribs); else aStack.back().m_bValid = false; break; @@ -278,6 +371,43 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re doKeyDerivation(aConvertedAttribs); else if (aConvertedName == sStartKeyAlgElement) //manifest:start-key-generation doStartKeyAlg(aConvertedAttribs); + else if (aConvertedName == sEncryptionMethodElement) //loext:encryption-method + doEncryptionMethod(aConvertedAttribs); + else if (aConvertedName == sKeyInfoElement) //loext:KeyInfo + doEncryptedKeyInfo(aConvertedAttribs); + else if (aConvertedName == sCipherDataElement) //loext:CipherData + doEncryptedCipherData(aConvertedAttribs); + else + aStack.back().m_bValid = false; + break; + } + case 5: { + ManifestStack::reverse_iterator aIter = aStack.rbegin(); + ++aIter; + + if (!aIter->m_bValid) + aStack.back().m_bValid = false; + else if (aConvertedName == sPgpDataElement) //loext:PGPData + doEncryptedPgpData(aConvertedAttribs); + else if (aConvertedName == sCipherValueElement) //loext:CipherValue + // ciphervalue action happens on endElement + aCurrentCharacters = ""; + else + aStack.back().m_bValid = false; + break; + } + case 6: { + ManifestStack::reverse_iterator aIter = aStack.rbegin(); + ++aIter; + + if (!aIter->m_bValid) + aStack.back().m_bValid = false; + else if (aConvertedName == sPgpKeyIDElement) //loext:PGPKeyID + // ciphervalue action happens on endElement + aCurrentCharacters = ""; + else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket + // ciphervalue action happens on endElement + aCurrentCharacters = ""; else aStack.back().m_bValid = false; break; @@ -298,9 +428,19 @@ bool isEmpty(const css::beans::PropertyValue &rProp) void SAL_CALL ManifestImport::endElement( const OUString& aName ) { + size_t nLevel = aStack.size(); + + assert(nLevel >= 1); + OUString aConvertedName = ConvertName( aName ); if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName == aConvertedName ) { if ( aConvertedName == sFileEntryElement && aStack.back().m_bValid ) { + // root folder gets KeyInfo entry if any, for PGP encryption + if (!bIgnoreEncryptData && !aKeys.empty() && aSequence[PKG_MNFST_FULLPATH].Value.get<OUString>() == "/" ) + { + aSequence[PKG_SIZE_NOENCR_MNFST].Name = "KeyInfo"; + aSequence[PKG_SIZE_NOENCR_MNFST].Value <<= comphelper::containerToSequence(aKeys); + } css::beans::PropertyValue aEmpty; aSequence.erase(std::remove_if(aSequence.begin(), aSequence.end(), isEmpty), aSequence.end()); @@ -310,13 +450,43 @@ void SAL_CALL ManifestImport::endElement( const OUString& aName ) aSequence.clear(); } + else if ( aConvertedName == sEncryptedKeyElement && aStack.back().m_bValid ) { + if ( !bIgnoreEncryptData ) + { + aKeys.push_back( comphelper::containerToSequence(aKeyInfoSequence) ); + bPgpEncryption = true; + } + aKeyInfoSequence.clear(); + } + + // end element handling for elements with cdata + switch (nLevel) { + case 5: { + if (aConvertedName == sCipherValueElement) //loext:CipherValue + doEncryptedCipherValue(); + else + aStack.back().m_bValid = false; + break; + } + case 6: { + if (aConvertedName == sPgpKeyIDElement) //loext:PGPKeyID + doEncryptedKeyId(); + else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket + doEncryptedKeyPacket(); + else + aStack.back().m_bValid = false; + break; + } + } aStack.pop_back(); + return; } } -void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ ) +void SAL_CALL ManifestImport::characters( const OUString& aChars ) { + aCurrentCharacters += aChars; } void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ ) diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx index 86cafa4ef1d7..26f692be9c5b 100644 --- a/package/source/manifest/ManifestImport.hxx +++ b/package/source/manifest/ManifestImport.hxx @@ -22,6 +22,7 @@ #include <cppuhelper/implbase.hxx> #include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/beans/NamedValue.hpp> #include <vector> #include <HashMaps.hxx> @@ -50,9 +51,13 @@ typedef ::std::vector< ManifestScopeEntry > ManifestStack; class ManifestImport final : public cppu::WeakImplHelper < css::xml::sax::XDocumentHandler > { + std::vector< css::beans::NamedValue > aKeyInfoSequence; + std::vector< css::uno::Sequence< css::beans::NamedValue > > aKeys; std::vector< css::beans::PropertyValue > aSequence; + OUString aCurrentCharacters; ManifestStack aStack; bool bIgnoreEncryptData; + bool bPgpEncryption; sal_Int32 nDerivedKeySize; ::std::vector < css::uno::Sequence < css::beans::PropertyValue > > & rManVector; @@ -76,6 +81,17 @@ class ManifestImport final : public cppu::WeakImplHelper < css::xml::sax::XDocum const OUString sChecksumAttribute; const OUString sChecksumTypeAttribute; + const OUString sKeyInfoElement; + const OUString sManifestKeyInfoElement; + const OUString sEncryptedKeyElement; + const OUString sEncryptionMethodElement; + const OUString sPgpDataElement; + const OUString sPgpKeyIDElement; + const OUString sPGPKeyPacketElement; + const OUString sAlgorithmAttribute; + const OUString sCipherDataElement; + const OUString sCipherValueElement; + const OUString sFullPathProperty; const OUString sMediaTypeProperty; const OUString sVersionProperty; @@ -136,6 +152,15 @@ private: void doKeyDerivation(StringHashMap &rConvertedAttribs); /// @throws css::uno::RuntimeException void doStartKeyAlg(StringHashMap &rConvertedAttribs); + void doKeyInfoEntry(StringHashMap &); + void doEncryptedKey(StringHashMap &); + void doEncryptionMethod(StringHashMap &); + void doEncryptedKeyInfo(StringHashMap &); + void doEncryptedCipherData(StringHashMap &); + void doEncryptedPgpData(StringHashMap &); + void doEncryptedCipherValue(); + void doEncryptedKeyId(); + void doEncryptedKeyPacket(); }; #endif diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx index 41d65fb97b7c..5c494a586197 100644 --- a/package/source/xstor/xstorage.cxx +++ b/package/source/xstor/xstorage.cxx @@ -4386,7 +4386,8 @@ void SAL_CALL OStorage::setPropertyValue( const OUString& aPropertyName, const u || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY || aPropertyName == IS_INCONSISTENT_PROPERTY || aPropertyName == "URL" - || aPropertyName == "RepairPackage" ) ) + || aPropertyName == "RepairPackage" + || aPropertyName == ENCRYPTION_GPG_PROPERTIES) ) || aPropertyName == "IsRoot" || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY ) throw beans::PropertyVetoException( THROW_WHERE ); @@ -4505,6 +4506,7 @@ uno::Any SAL_CALL OStorage::getPropertyValue( const OUString& aPropertyName ) else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY + || aPropertyName == ENCRYPTION_GPG_PROPERTIES || aPropertyName == IS_INCONSISTENT_PROPERTY ) ) { try { diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx index 162bab6d7580..d20b46195c3a 100644 --- a/package/source/zipapi/XUnbufferedStream.cxx +++ b/package/source/zipapi/XUnbufferedStream.cxx @@ -78,7 +78,10 @@ XUnbufferedStream::XUnbufferedStream( if (mnZipSize < 0) throw ZipIOException("The stream seems to be broken!"); - bool bHaveEncryptData = rData.is() && rData->m_aSalt.getLength() && rData->m_aInitVector.getLength() && rData->m_nIterationCount != 0; + bool bHaveEncryptData = rData.is() && rData->m_aInitVector.getLength() && + ((rData->m_aSalt.getLength() && rData->m_nIterationCount != 0) + || + rData->m_aKey.getLength()); bool bMustDecrypt = nStreamMode == UNBUFF_STREAM_DATA && bHaveEncryptData && bIsEncrypted; if ( bMustDecrypt ) diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index de4c1a364acd..f772287eeaf8 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -161,7 +161,14 @@ uno::Reference< xml::crypto::XCipherContext > ZipFile::StaticGetCipher( const un } uno::Sequence< sal_Int8 > aDerivedKey( xEncryptionData->m_nDerivedKeySize ); - if ( rtl_Digest_E_None != rtl_digest_PBKDF2( reinterpret_cast< sal_uInt8* >( aDerivedKey.getArray() ), + if ( !xEncryptionData->m_nIterationCount && + xEncryptionData->m_nDerivedKeySize == xEncryptionData->m_aKey.getLength() ) + { + // gpg4libre: no need to derive key, m_aKey is already + // usable as symmetric session key + aDerivedKey = xEncryptionData->m_aKey; + } + else if ( rtl_Digest_E_None != rtl_digest_PBKDF2( reinterpret_cast< sal_uInt8* >( aDerivedKey.getArray() ), aDerivedKey.getLength(), reinterpret_cast< const sal_uInt8 * > (xEncryptionData->m_aKey.getConstArray() ), xEncryptionData->m_aKey.getLength(), diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 5e61d4678490..9a4853f439c6 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -198,12 +198,14 @@ void ZipPackage::parseManifest() const OUString sPropDigestAlgorithm ("DigestAlgorithm"); const OUString sPropEncryptionAlgorithm ("EncryptionAlgorithm"); const OUString sPropStartKeyAlgorithm ("StartKeyAlgorithm"); + const OUString sKeyInfo ("KeyInfo"); uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() ); sal_Int32 nLength = aManifestSequence.getLength(); const uno::Sequence < PropertyValue > *pSequence = aManifestSequence.getConstArray(); ZipPackageStream *pStream = nullptr; ZipPackageFolder *pFolder = nullptr; + const Any *pKeyInfo = nullptr; for ( sal_Int32 i = 0; i < nLength ; i++, pSequence++ ) { @@ -236,6 +238,8 @@ void ZipPackage::parseManifest() pStartKeyAlg = &( pValue[j].Value ); else if ( pValue[j].Name == sPropDerivedKeySize ) pDerivedKeySize = &( pValue[j].Value ); + else if ( pValue[j].Name == sKeyInfo ) + pKeyInfo = &( pValue[j].Value ); } if ( !sPath.isEmpty() && hasByHierarchicalName ( sPath ) ) @@ -256,7 +260,51 @@ void ZipPackage::parseManifest() pStream->SetMediaType ( sMediaType ); pStream->SetFromManifest( true ); - if ( pSalt && pVector && pCount && pSize && pDigest && pDigestAlg && pEncryptionAlg ) + if ( pKeyInfo && pVector && pSize && pDigest && pDigestAlg && pEncryptionAlg ) + { + uno::Sequence < sal_Int8 > aSequence; + sal_Int64 nSize = 0; + sal_Int32 nDigestAlg = 0, nEncryptionAlg = 0; + + pStream->SetToBeEncrypted ( true ); + + *pVector >>= aSequence; + pStream->setInitialisationVector ( aSequence ); + + *pSize >>= nSize; + pStream->setSize ( nSize ); + + *pDigest >>= aSequence; + pStream->setDigest ( aSequence ); + + *pDigestAlg >>= nDigestAlg; + pStream->SetImportedChecksumAlgorithm( nDigestAlg ); + + *pEncryptionAlg >>= nEncryptionAlg; + pStream->SetImportedEncryptionAlgorithm( nEncryptionAlg ); + + *pKeyInfo >>= m_aGpgProps; + + pStream->SetToBeCompressed ( true ); + pStream->SetToBeEncrypted ( true ); + pStream->SetIsEncrypted ( true ); + pStream->setIterationCount(0); + + // clamp to default SHA256 start key magic value, + // c.f. ZipPackageStream::GetEncryptionKey() + // trying to get key value from properties + const sal_Int32 nStartKeyAlg = xml::crypto::DigestID::SHA256; + pStream->SetImportedStartKeyAlgorithm( nStartKeyAlg ); + + if ( !m_bHasEncryptedEntries && pStream->getName() == "content.xml" ) + { + m_bHasEncryptedEntries = true; + m_nChecksumDigestID = nDigestAlg; + m_nCommonEncryptionID = nEncryptionAlg; + m_nStartKeyGenerationID = nStartKeyAlg; + } + } + else if ( pSalt && pVector && pCount && pSize && pDigest && pDigestAlg && pEncryptionAlg ) { uno::Sequence < sal_Int8 > aSequence; sal_Int64 nSize = 0; @@ -1203,10 +1251,10 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile() const OUString sMediaType ("MediaType"); const OUString sVersion ("Version"); const OUString sFullPath ("FullPath"); + const bool bIsGpgEncrypt = m_aGpgProps.hasElements(); if ( m_nFormat == embed::StorageFormats::PACKAGE ) { - bool bIsGpgEncrypt = m_aGpgProps.hasElements(); uno::Sequence < PropertyValue > aPropSeq( bIsGpgEncrypt ? PKG_SIZE_NOENCR_MNFST+1 : PKG_SIZE_NOENCR_MNFST ); aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType; @@ -1229,8 +1277,10 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile() // for encrypted streams RandomPool aRandomPool; + sal_Int32 const nPBKDF2IterationCount = 100000; + // call saveContents ( it will recursively save sub-directories - m_xRootFolder->saveContents("", aManList, aZipOut, GetEncryptionKey(), aRandomPool.get()); + m_xRootFolder->saveContents("", aManList, aZipOut, GetEncryptionKey(), bIsGpgEncrypt ? 0 : nPBKDF2IterationCount, aRandomPool.get()); } if( m_nFormat == embed::StorageFormats::PACKAGE ) @@ -1759,7 +1809,7 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const else if ( aPropertyName == ENCRYPTION_GPG_PROPERTIES ) { uno::Sequence< uno::Sequence< beans::NamedValue > > aGpgProps; - if ( m_pZipFile || !( aValue >>= aGpgProps ) || aGpgProps.getLength() == 0 ) + if ( !( aValue >>= aGpgProps ) || aGpgProps.getLength() == 0 ) { throw IllegalArgumentException(THROW_WHERE "unexpected Gpg properties are provided.", uno::Reference< uno::XInterface >(), 2 ); } @@ -1802,6 +1852,10 @@ Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName ) { return Any(m_bHasEncryptedEntries); } + else if ( PropertyName == ENCRYPTION_GPG_PROPERTIES ) + { + return Any(m_aGpgProps); + } else if ( PropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY ) { return Any(m_bHasNonEncryptedEntries); diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx index f70a048b393a..01b4789720b8 100644 --- a/package/source/zippackage/ZipPackageFolder.cxx +++ b/package/source/zippackage/ZipPackageFolder.cxx @@ -258,6 +258,7 @@ bool ZipPackageFolder::saveChild( std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool) { const OUString sMediaTypeProperty ("MediaType"); @@ -279,7 +280,7 @@ bool ZipPackageFolder::saveChild( else aPropSet.realloc( 0 ); - saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool); + saveContents( sTempName, rManList, rZipOut, rEncryptionKey, nPBKDF2IterationCount, rRandomPool); // folder can have a mediatype only in package format if ( aPropSet.getLength() && ( m_nFormat == embed::StorageFormats::PACKAGE ) ) @@ -293,6 +294,7 @@ void ZipPackageFolder::saveContents( std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool ) const { bool bWritingFailed = false; @@ -331,7 +333,7 @@ void ZipPackageFolder::saveContents( { bMimeTypeStreamStored = true; bWritingFailed = !aIter->second->pStream->saveChild( - rPath + aIter->first, rManList, rZipOut, rEncryptionKey, rRandomPool ); + rPath + aIter->first, rManList, rZipOut, rEncryptionKey, nPBKDF2IterationCount, rRandomPool ); } } @@ -347,12 +349,12 @@ void ZipPackageFolder::saveContents( if (rInfo.bFolder) { bWritingFailed = !rInfo.pFolder->saveChild( - rPath + rShortName, rManList, rZipOut, rEncryptionKey, rRandomPool ); + rPath + rShortName, rManList, rZipOut, rEncryptionKey, nPBKDF2IterationCount, rRandomPool ); } else { bWritingFailed = !rInfo.pStream->saveChild( - rPath + rShortName, rManList, rZipOut, rEncryptionKey, rRandomPool ); + rPath + rShortName, rManList, rZipOut, rEncryptionKey, nPBKDF2IterationCount, rRandomPool ); } } } diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index 160dfa8d310f..f415995a125e 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -502,6 +502,7 @@ bool ZipPackageStream::saveChild( std::vector < uno::Sequence < beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, + sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool) { bool bSuccess = true; @@ -647,8 +648,6 @@ bool ZipPackageStream::saveChild( uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( GetBlockSize() ); rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 ); rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() ); - sal_Int32 const nPBKDF2IterationCount = 100000; - if ( !m_bHaveOwnKey ) { m_aEncryptionKey = rEncryptionKey; |