[libreoffice] Patch to backport reading AES-encrypted ODF 1.2 documents

sbergmann sbergmann at fedoraproject.org
Thu Nov 10 09:48:52 UTC 2011


commit e7a803540d408adab3d55fb2ae051ac4be599a72
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Nov 10 10:48:41 2011 +0100

    Patch to backport reading AES-encrypted ODF 1.2 documents

 ...t-reading-AES-encrypted-ODF-1.2-documents.patch | 8199 ++++++++++++++++++++
 libreoffice.spec                                   |    7 +-
 2 files changed, 8205 insertions(+), 1 deletions(-)
---
diff --git a/Backport-reading-AES-encrypted-ODF-1.2-documents.patch b/Backport-reading-AES-encrypted-ODF-1.2-documents.patch
new file mode 100644
index 0000000..e6c7225
--- /dev/null
+++ b/Backport-reading-AES-encrypted-ODF-1.2-documents.patch
@@ -0,0 +1,8199 @@
+From 8055f25337fd5141b50382e9939c9a018c33f1c3 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman at redhat.com>
+Date: Wed, 9 Nov 2011 08:54:35 +0100
+Subject: [PATCH] Backport reading AES-encrypted ODF 1.2 documents (as
+ genereated by LibO 3.5).
+
+This backports the reading half of CWS mav60 plus <http://cgit.freedesktop.org/
+libreoffice/core/commit/?id=2d775f593abd9bc487ccc60f06aa5a3ca9632056> "Produce
+correct sha256 uri, consume correct uri and original spec typo."  It spans the
+repos components, libs-core, libs-gui, and ure.
+---
+ package/inc/EncryptedDataHeader.hxx                |    8 +-
+ package/inc/EncryptionData.hxx                     |   52 ++-
+ package/inc/PackageConstants.hxx                   |   20 +-
+ package/inc/ZipFile.hxx                            |   35 +-
+ package/inc/ZipOutputStream.hxx                    |   37 +-
+ package/inc/ZipPackage.hxx                         |   15 +-
+ package/inc/ZipPackageEntry.hxx                    |  106 ++++
+ package/inc/ZipPackageFolder.hxx                   |    4 +-
+ package/inc/ZipPackageStream.hxx                   |  216 ++++++++
+ package/qa/storages/TestHelper.java                |   16 +-
+ package/source/manifest/Base64Codec.cxx            |    8 +-
+ package/source/manifest/Base64Codec.hxx            |    4 +-
+ package/source/manifest/ManifestDefines.hxx        |   20 +
+ package/source/manifest/ManifestExport.cxx         |    2 +-
+ package/source/manifest/ManifestImport.cxx         |  134 +++++-
+ package/source/manifest/ManifestImport.hxx         |   29 +-
+ package/source/xstor/owriteablestream.cxx          |  162 +++----
+ package/source/xstor/xstorage.cxx                  |  139 +++++-
+ package/source/xstor/xstorage.hxx                  |    9 +-
+ package/source/zipapi/EntryInputStream.cxx         |  205 --------
+ package/source/zipapi/EntryInputStream.hxx         |   85 ----
+ package/source/zipapi/XFileStream.cxx              |  230 ---------
+ package/source/zipapi/XFileStream.hxx              |   95 ----
+ package/source/zipapi/XMemoryStream.cxx            |   55 --
+ package/source/zipapi/XMemoryStream.hxx            |   45 --
+ package/source/zipapi/XUnbufferedStream.cxx        |   75 ++--
+ package/source/zipapi/XUnbufferedStream.hxx        |   13 +-
+ package/source/zipapi/ZipFile.cxx                  |  288 ++++++++---
+ package/source/zipapi/ZipOutputStream.cxx          |  102 +++--
+ package/source/zipapi/blowfishcontext.cxx          |  122 +++++
+ package/source/zipapi/blowfishcontext.hxx          |   58 +++
+ package/source/zipapi/makefile.mk                  |    2 +
+ package/source/zipapi/sha1context.cxx              |   97 ++++
+ package/source/zipapi/sha1context.hxx              |   57 +++
+ package/source/zippackage/ZipPackage.cxx           |  252 ++++++++--
+ package/source/zippackage/ZipPackageEntry.hxx      |  106 ----
+ package/source/zippackage/ZipPackageFolder.cxx     |   54 ++-
+ package/source/zippackage/ZipPackageStream.cxx     |  238 +++++++--
+ package/source/zippackage/ZipPackageStream.hxx     |  196 --------
+ package/source/zippackage/zipfileaccess.cxx        |    5 +-
+ .../inc/xmlsecurity/digitalsignaturesdialog.hxx    |    2 +-
+ xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx |    5 +-
+ .../source/component/documentdigitalsignatures.cxx |    8 +-
+ .../source/dialogs/digitalsignaturesdialog.cxx     |    4 +-
+ xmlsecurity/source/helper/xmlsignaturehelper.cxx   |    6 +-
+ xmlsecurity/source/xmlsec/makefile.mk              |    6 +-
+ xmlsecurity/source/xmlsec/nss/ciphercontext.cxx    |  276 +++++++++++
+ xmlsecurity/source/xmlsec/nss/ciphercontext.hxx    |   89 ++++
+ xmlsecurity/source/xmlsec/nss/digestcontext.cxx    |  101 ++++
+ xmlsecurity/source/xmlsec/nss/digestcontext.hxx    |   68 +++
+ xmlsecurity/source/xmlsec/nss/makefile.mk          |   20 +-
+ xmlsecurity/source/xmlsec/nss/nssinitializer.cxx   |  521 ++++++++++++++++++++
+ xmlsecurity/source/xmlsec/nss/nssinitializer.hxx   |   90 ++++
+ .../xmlsec/nss/securityenvironment_nssimpl.cxx     |   38 ++-
+ .../source/xmlsec/nss/seinitializer_nssimpl.cxx    |  355 +-------------
+ .../source/xmlsec/nss/seinitializer_nssimpl.hxx    |   34 +-
+ .../source/xmlsec/nss/x509certificate_nssimpl.cxx  |   28 +-
+ xmlsecurity/source/xmlsec/nss/xsec_nss.cxx         |   34 +-
+ xmlsecurity/source/xmlsec/xsec_xmlsec.cxx          |    4 -
+ xmlsecurity/util/makefile.mk                       |   10 +-
+ xmlsecurity/util/xsec_xmlsec.component             |    1 +
+ xmlsecurity/util/xsec_xmlsec.windows.component     |    3 +
+ 62 files changed, 3208 insertions(+), 1891 deletions(-)
+ create mode 100644 package/inc/ZipPackageEntry.hxx
+ create mode 100644 package/inc/ZipPackageStream.hxx
+ delete mode 100644 package/source/zipapi/EntryInputStream.cxx
+ delete mode 100644 package/source/zipapi/EntryInputStream.hxx
+ delete mode 100644 package/source/zipapi/XFileStream.cxx
+ delete mode 100644 package/source/zipapi/XFileStream.hxx
+ delete mode 100644 package/source/zipapi/XMemoryStream.cxx
+ delete mode 100644 package/source/zipapi/XMemoryStream.hxx
+ create mode 100644 package/source/zipapi/blowfishcontext.cxx
+ create mode 100644 package/source/zipapi/blowfishcontext.hxx
+ create mode 100644 package/source/zipapi/sha1context.cxx
+ create mode 100644 package/source/zipapi/sha1context.hxx
+ delete mode 100644 package/source/zippackage/ZipPackageEntry.hxx
+ delete mode 100644 package/source/zippackage/ZipPackageStream.hxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/ciphercontext.cxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/ciphercontext.hxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/digestcontext.cxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/digestcontext.hxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
+ create mode 100644 xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
+
+diff --git a/package/inc/EncryptedDataHeader.hxx b/package/inc/EncryptedDataHeader.hxx
+index 88cdaa5..4e35664 100644
+--- a/package/inc/EncryptedDataHeader.hxx
++++ b/package/inc/EncryptedDataHeader.hxx
+@@ -36,6 +36,10 @@
+    Version number   2 bytes
+    Iteraction count 4 bytes
+    Size				4 bytes
++   EncAlgorithm      4 bytes
++   DigestAlgorithm   4 bytes
++   DerivedKeySize    4 bytes
++   StartKeyAlgorithm 4 bytes
+    Salt length		2 bytes
+    IV length		2 bytes
+    Digest length	2 bytes
+@@ -46,8 +50,8 @@
+    MediaType		X bytes
+ 
+ */
+-const sal_uInt32 n_ConstHeader = 0x0502474dL; // "MG\002\005"
+-const sal_Int32 n_ConstHeaderSize = 22; // + salt length + iv length + digest length + mediatype length
++const sal_uInt32 n_ConstHeader = 0x05024d4dL; // "MM\002\005"
++const sal_Int32 n_ConstHeaderSize = 38; // + salt length + iv length + digest length + mediatype length
+ const sal_Int16 n_ConstCurrentVersion = 1; 
+ #endif
+ 
+diff --git a/package/inc/EncryptionData.hxx b/package/inc/EncryptionData.hxx
+index 4dba2e3..1662510 100644
+--- a/package/inc/EncryptionData.hxx
++++ b/package/inc/EncryptionData.hxx
+@@ -31,16 +31,54 @@
+ #include <com/sun/star/uno/Sequence.hxx>
+ #include <cppuhelper/weak.hxx>
+ 
+-class EncryptionData : public cppu::OWeakObject
++class BaseEncryptionData : public cppu::OWeakObject
+ {
+ public:
+-    // On export aKey holds the derived key
+-    // On import aKey holds the hash of the user enterred key
+-    com::sun::star::uno::Sequence < sal_Int8 > aKey;
+-    com::sun::star::uno::Sequence < sal_uInt8 > aSalt, aInitVector, aDigest;
+-    sal_Int32 nIterationCount;
+-    EncryptionData(): nIterationCount ( 0 ){}
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aSalt;
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aInitVector;
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aDigest;
++    sal_Int32 m_nIterationCount;
++
++    BaseEncryptionData()
++    : m_nIterationCount ( 0 ){}
++
++    BaseEncryptionData( const BaseEncryptionData& aData )
++    : cppu::OWeakObject()
++    , m_aSalt( aData.m_aSalt )
++    , m_aInitVector( aData.m_aInitVector )
++    , m_aDigest( aData.m_aDigest )
++    , m_nIterationCount( aData.m_nIterationCount )
++    {}
+ };
++
++class EncryptionData : public BaseEncryptionData
++{
++public:
++    ::com::sun::star::uno::Sequence < sal_Int8 > m_aKey;
++    sal_Int32 m_nEncAlg;
++    sal_Int32 m_nCheckAlg;
++    sal_Int32 m_nDerivedKeySize;
++    sal_Int32 m_nStartKeyGenID;
++
++    EncryptionData( const BaseEncryptionData& aData, const ::com::sun::star::uno::Sequence< sal_Int8 >& aKey, sal_Int32 nEncAlg, sal_Int32 nCheckAlg, sal_Int32 nDerivedKeySize, sal_Int32 nStartKeyGenID )
++    : BaseEncryptionData( aData )
++    , m_aKey( aKey )
++    , m_nEncAlg( nEncAlg )
++    , m_nCheckAlg( nCheckAlg )
++    , m_nDerivedKeySize( nDerivedKeySize )
++    , m_nStartKeyGenID( nStartKeyGenID )
++    {}
++
++    EncryptionData( const EncryptionData& aData )
++    : BaseEncryptionData( aData )
++    , m_aKey( aData.m_aKey )
++    , m_nEncAlg( aData.m_nEncAlg )
++    , m_nCheckAlg( aData.m_nCheckAlg )
++    , m_nDerivedKeySize( aData.m_nDerivedKeySize )
++    , m_nStartKeyGenID( aData.m_nStartKeyGenID )
++    {}
++};
++
+ #endif
+ 
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/inc/PackageConstants.hxx b/package/inc/PackageConstants.hxx
+index 229f739..7507ada 100644
+--- a/package/inc/PackageConstants.hxx
++++ b/package/inc/PackageConstants.hxx
+@@ -32,7 +32,12 @@
+ 
+ const sal_Int32 n_ConstBufferSize = 32768;
+ const sal_Int32 n_ConstMaxMemoryStreamSize = 20480;
++
++// by calculation of the digest we read 32 bytes more ( if available )
++// it allows to ignore the padding if the stream is longer than n_ConstDigestDecrypt since we read at least two blocks more;
++// if the stream is shorter or equal the padding will be done successfully
+ const sal_Int32 n_ConstDigestLength = 1024;
++const sal_Int32 n_ConstDigestDecrypt = 1056; // 1024 + 32
+ 
+ // the constants related to the manifest.xml entries
+ #define PKG_MNFST_MEDIATYPE 0
+@@ -44,9 +49,22 @@ const sal_Int32 n_ConstDigestLength = 1024;
+ #define PKG_MNFST_ITERATION 5
+ #define PKG_MNFST_UCOMPSIZE 6
+ #define PKG_MNFST_DIGEST    7
++#define PKG_MNFST_ENCALG      8
++#define PKG_MNFST_STARTALG    9
++#define PKG_MNFST_DIGESTALG  10
++#define PKG_MNFST_DERKEYSIZE 11
+ 
+ #define PKG_SIZE_NOENCR_MNFST 3
+-#define PKG_SIZE_ENCR_MNFST   8
++#define PKG_SIZE_ENCR_MNFST   12
++
++// the properties related constants
++#define ENCRYPTION_KEY_PROPERTY "EncryptionKey"
++#define STORAGE_ENCRYPTION_KEYS_PROPERTY "StorageEncryptionKeys"
++#define ENCRYPTION_ALGORITHMS_PROPERTY "EncryptionAlgorithms"
++#define HAS_ENCRYPTED_ENTRIES_PROPERTY "HasEncryptedEntries"
++#define HAS_NONENCRYPTED_ENTRIES_PROPERTY "HasNonEncryptedEntries"
++#define IS_INCONSISTENT_PROPERTY "IsInconsistent"
++#define MEDIATYPE_FALLBACK_USED_PROPERTY "MediaTypeFallbackUsed"
+ 
+ 
+ #endif
+diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
+index c64500c..bd108b3 100644
+--- a/package/inc/ZipFile.hxx
++++ b/package/inc/ZipFile.hxx
+@@ -32,9 +32,15 @@
+ #include <com/sun/star/packages/zip/ZipIOException.hpp>
+ #include <com/sun/star/packages/NoEncryptionException.hpp>
+ #include <com/sun/star/packages/WrongPasswordException.hpp>
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++
++#include <rtl/ref.hxx>
++
+ #include <ByteGrabber.hxx>
+ #include <HashMaps.hxx>
+ #include <Inflater.hxx>
++#include <EncryptionData.hxx>
+ 
+ #include <mutexholder.hxx>
+ 
+@@ -56,7 +62,6 @@ namespace rtl
+ 
+ typedef void* rtlCipher;
+ class ZipEnumeration;
+-class EncryptionData;
+ 
+ class ZipFile
+ {
+@@ -69,7 +74,7 @@ protected:
+     ZipUtils::Inflater aInflater;
+     com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+     com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
+-    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > xFactory;
++    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+     ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
+ 
+     sal_Bool bRecoveryMode;
+@@ -133,25 +138,41 @@ public:
+ 
+     static sal_Bool StaticGetCipher ( const rtl::Reference < EncryptionData > & xEncryptionData, rtlCipher &rCipher, sal_Bool bDecode );
+ 
+-    static void StaticFillHeader ( const rtl::Reference < EncryptionData > & rData,
++    static ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext > StaticGetDigestContextForChecksum(
++            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xArgFactory,
++            const ::rtl::Reference< EncryptionData >& xEncryptionData );
++
++    static ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > StaticGetCipher(
++            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xArgFactory,
++            const ::rtl::Reference< EncryptionData >& xEncryptionData,
++            bool bEncrypt );
++
++    static void StaticFillHeader ( const ::rtl::Reference < EncryptionData > & rData,
+                                     sal_Int32 nSize,
+                                     const ::rtl::OUString& aMediaType,
+                                     sal_Int8 * & pHeader );
+ 
+-    static sal_Bool StaticFillData ( rtl::Reference < EncryptionData > & rData,
++    static sal_Bool StaticFillData ( ::rtl::Reference < BaseEncryptionData > & rData,
++                                     sal_Int32 &rEncAlgorithm,
++                                     sal_Int32 &rChecksumAlgorithm,
++                                     sal_Int32 &rDerivedKeySize,
++                                     sal_Int32 &rStartKeyGenID,
+                                      sal_Int32 &rSize,
+                                      ::rtl::OUString& aMediaType,
+-                                     ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &rStream );
++                                     const ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream );
+ 
+     static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > StaticGetDataFromRawStream(
++            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
+             const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xStream,
+             const rtl::Reference < EncryptionData > &rData )
+         throw ( ::com::sun::star::packages::WrongPasswordException,
+                 ::com::sun::star::packages::zip::ZipIOException,
+                 ::com::sun::star::uno::RuntimeException );
+ 
+-    static sal_Bool StaticHasValidPassword ( const ::com::sun::star::uno::Sequence< sal_Int8 > &aReadBuffer,
+-                                             const rtl::Reference < EncryptionData > &rData );
++    static sal_Bool StaticHasValidPassword (
++            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
++            const ::com::sun::star::uno::Sequence< sal_Int8 > &aReadBuffer,
++            const ::rtl::Reference < EncryptionData > &rData );
+ 
+ 
+     ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(
+diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
+index b36f4d2..506e913 100644
+--- a/package/inc/ZipOutputStream.hxx
++++ b/package/inc/ZipOutputStream.hxx
+@@ -28,39 +28,48 @@
+ #ifndef _ZIP_OUTPUT_STREAM_HXX
+ #define _ZIP_OUTPUT_STREAM_HXX
+ 
++#include <com/sun/star/uno/Reference.hxx>
++#include <com/sun/star/lang/XMultiServiceFactory.hpp>
++#include <com/sun/star/io/XOutputStream.hpp>
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++
+ #include <ByteChucker.hxx>
+ #include <Deflater.hxx>
+ #include <CRC32.hxx>
+-#include <rtl/cipher.h>
+-#include <rtl/digest.h>
+ 
+ #include <vector>
+ 
+ struct ZipEntry;
+-class EncryptionData;
+-namespace rtl
+-{
+-    template < class T > class Reference;
+-}
++class ZipPackageStream;
++
+ class ZipOutputStream
+ {
+ protected:
+-    com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > xStream;
++    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream;
++
+     ::std::vector < ZipEntry * >			aZipList;
+-    com::sun::star::uno::Sequence < sal_Int8 > aBuffer, aEncryptionBuffer;
++
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
++
+     ::rtl::OUString		sComment;
+     ZipUtils::Deflater	aDeflater;
+-    rtlCipher 			aCipher;
+-    rtlDigest 			aDigest;
++
++    ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext;
++    ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext > m_xDigestContext;
++
+     CRC32				aCRC;
+     ByteChucker			aChucker;
+     ZipEntry 			*pCurrentEntry;
+     sal_Int16			nMethod, nLevel, mnDigested;
+     sal_Bool			bFinished, bEncryptCurrentEntry;
+-    EncryptionData 		*pCurrentEncryptData;
++    ZipPackageStream*   m_pCurrentStream;
+ 
+ public:
+-    ZipOutputStream( com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > &xOStream );
++    ZipOutputStream(
++        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
++        const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > &xOStream );
+     ~ZipOutputStream();
+     
+     // rawWrite to support a direct write to the output stream
+@@ -75,7 +84,7 @@ public:
+     void SAL_CALL setLevel( sal_Int32 nNewLevel )
+         throw(::com::sun::star::uno::RuntimeException);
+     void SAL_CALL putNextEntry( ZipEntry& rEntry, 
+-            rtl::Reference < EncryptionData > &rData,
++            ZipPackageStream* pStream,
+             sal_Bool bEncrypt = sal_False )
+         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+     void SAL_CALL closeEntry(  )
+diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
+index 8ea3f60..a4aed11 100644
+--- a/package/inc/ZipPackage.hxx
++++ b/package/inc/ZipPackage.hxx
+@@ -36,7 +36,9 @@
+ #include <com/sun/star/lang/XUnoTunnel.hpp>
+ #include <com/sun/star/beans/XPropertySet.hpp>
+ #include <com/sun/star/beans/PropertyValue.hpp>
++#include <com/sun/star/beans/NamedValue.hpp>
+ #include <com/sun/star/lang/XServiceInfo.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
+ #include <HashMaps.hxx>
+ #include <com/sun/star/lang/IllegalArgumentException.hpp>
+ #include <osl/file.h>
+@@ -83,13 +85,17 @@ class ZipPackage : public cppu::WeakImplHelper7
+ protected:
+     SotMutexHolderRef m_aMutexHolder;
+ 
++    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > m_aStorageEncryptionKeys;
+     ::com::sun::star::uno::Sequence < sal_Int8 > m_aEncryptionKey;
+     FolderHash 		 m_aRecent;
+     ::rtl::OUString	 m_aURL;
++
++    sal_Int32         m_nStartKeyGenerationID;
++    sal_Int32         m_nChecksumDigestID;
++    sal_Int32         m_nCommonEncryptionID;
+     sal_Bool 		 m_bHasEncryptedEntries;
+     sal_Bool 		 m_bHasNonEncryptedEntries;
+     sal_Bool 		 m_bInconsistent;
+-    sal_Bool 		 m_bUseManifest;
+     sal_Bool		 m_bForceRecovery;
+ 
+     sal_Bool		m_bMediaTypeFallbackUsed;
+@@ -124,12 +130,17 @@ public:
+     ZipPackage (const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory);
+     virtual ~ZipPackage( void );
+     ZipFile& getZipFile() { return *m_pZipFile;}
+-    const com::sun::star::uno::Sequence < sal_Int8 > & getEncryptionKey ( ) {return m_aEncryptionKey;}
+     sal_Int32 getFormat() const { return m_nFormat; }
+ 
++    sal_Int32 GetStartKeyGenID() const { return m_nStartKeyGenerationID; }
++    sal_Int32 GetEncAlgID() const { return m_nCommonEncryptionID; }
++    sal_Int32 GetChecksumAlgID() const { return m_nChecksumDigestID; }
++    sal_Int32 GetDefaultDerivedKeySize() const { return m_nCommonEncryptionID == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 32 : 16; }
++
+     SotMutexHolderRef GetSharedMutexRef() { return m_aMutexHolder; }
+ 
+     void ConnectTo( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream );
++    const ::com::sun::star::uno::Sequence< sal_Int8 > GetEncryptionKey();
+ 
+     // XInitialization
+     virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+diff --git a/package/inc/ZipPackageEntry.hxx b/package/inc/ZipPackageEntry.hxx
+new file mode 100644
+index 0000000..18adfdc
+--- /dev/null
++++ b/package/inc/ZipPackageEntry.hxx
+@@ -0,0 +1,106 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef _ZIP_PACKAGE_ENTRY_HXX
++#define _ZIP_PACKAGE_ENTRY_HXX
++
++#include <com/sun/star/container/XChild.hpp>
++#include <com/sun/star/container/XNamed.hpp>
++#include <com/sun/star/beans/XPropertySet.hpp>
++#include <com/sun/star/lang/XUnoTunnel.hpp>
++#include <com/sun/star/container/XNameContainer.hpp>
++#include <com/sun/star/lang/XServiceInfo.hpp>
++#include <ZipEntry.hxx>
++#include <cppuhelper/implbase5.hxx>
++
++class ZipPackageFolder;
++
++class ZipPackageEntry : public cppu::WeakImplHelper5
++<
++    com::sun::star::container::XNamed,
++    com::sun::star::container::XChild,
++    com::sun::star::lang::XUnoTunnel,
++    com::sun::star::beans::XPropertySet,
++    com::sun::star::lang::XServiceInfo
++>
++{
++protected:
++    ::rtl::OUString msName;
++    bool mbIsFolder:1;
++    bool mbAllowRemoveOnInsert:1;
++    // com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > xParent;
++    ::rtl::OUString		sMediaType;
++    ZipPackageFolder * pParent;
++public:
++    ZipEntry aEntry;
++    ZipPackageEntry ( bool bNewFolder = sal_False );
++    virtual ~ZipPackageEntry( void );
++
++    ::rtl::OUString & GetMediaType () { return sMediaType; }
++    void SetMediaType ( const ::rtl::OUString & sNewType) { sMediaType = sNewType; }
++    void doSetParent ( ZipPackageFolder * pNewParent, sal_Bool bInsert );
++    bool IsFolder ( ) { return mbIsFolder; }
++    ZipPackageFolder* GetParent ( ) { return pParent; }
++    void SetFolder ( bool bSetFolder ) { mbIsFolder = bSetFolder; }
++
++    void clearParent ( void )
++    {
++        // xParent.clear();
++        pParent = NULL;
++    }
++    // XNamed
++    virtual ::rtl::OUString SAL_CALL getName(  )
++        throw(::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL setName( const ::rtl::OUString& aName )
++        throw(::com::sun::star::uno::RuntimeException);
++    // XChild
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent(  )
++        throw(::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent )
++        throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
++    // XUnoTunnel
++    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
++        throw(::com::sun::star::uno::RuntimeException) = 0;
++    // XPropertySet
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  )
++        throw(::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
++    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
++    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++};
++#endif
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx
+index c6ace8e..59be1b7 100644
+--- a/package/inc/ZipPackageFolder.hxx
++++ b/package/inc/ZipPackageFolder.hxx
+@@ -92,10 +92,10 @@ public:
+     void setPackageFormat_Impl( sal_Int32 nFormat ) { m_nFormat = nFormat; }
+     void setRemoveOnInsertMode_Impl( sal_Bool bRemove ) { this->mbAllowRemoveOnInsert = bRemove; }
+ 
+-    bool saveChild(const rtl::OUString &rShortName, const com::sun::star::packages::ContentInfo &rInfo, rtl::OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, com::sun::star::uno::Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool & rRandomPool);
++    bool saveChild(const rtl::OUString &rShortName, const com::sun::star::packages::ContentInfo &rInfo, rtl::OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const com::sun::star::uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool & rRandomPool);
+ 
+     // Recursive functions
+-    void  saveContents(rtl::OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, com::sun::star::uno::Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool & rRandomPool)
++    void  saveContents(rtl::OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const com::sun::star::uno::Sequence< sal_Int8 > &rEncryptionKey, rtlRandomPool & rRandomPool)
+         throw(::com::sun::star::uno::RuntimeException);
+     void  releaseUpwardRef();
+ 
+diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx
+new file mode 100644
+index 0000000..a3bbf73
+--- /dev/null
++++ b/package/inc/ZipPackageStream.hxx
+@@ -0,0 +1,216 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef _ZIP_PACKAGE_STREAM_HXX
++#define _ZIP_PACKAGE_STREAM_HXX
++
++#include <com/sun/star/io/XActiveDataSink.hpp>
++#include <com/sun/star/io/XSeekable.hpp>
++#include <com/sun/star/beans/NamedValue.hpp>
++#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
++
++#include <rtl/ref.hxx>
++#include <cppuhelper/implbase2.hxx>
++
++#include <ZipPackageEntry.hxx>
++#include <EncryptionData.hxx>
++#include <mutexholder.hxx>
++
++#define PACKAGE_STREAM_NOTSET           0
++#define PACKAGE_STREAM_PACKAGEMEMBER    1
++#define PACKAGE_STREAM_DETECT           2
++#define PACKAGE_STREAM_DATA             3
++#define PACKAGE_STREAM_RAW              4
++
++class ZipPackage;
++struct ZipEntry;
++class ZipPackageStream : public cppu::ImplInheritanceHelper2
++<
++    ZipPackageEntry,
++    ::com::sun::star::io::XActiveDataSink,
++    ::com::sun::star::packages::XDataSinkEncrSupport
++>
++{
++protected:
++    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
++    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
++    ZipPackage          &rZipPackage;
++    sal_Bool            bToBeCompressed, bToBeEncrypted, bHaveOwnKey, bIsEncrypted;
++
++    ::rtl::Reference< BaseEncryptionData > m_xBaseEncryptionData;
++    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > m_aStorageEncryptionKeys;
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aEncryptionKey;
++
++    sal_Int32 m_nImportedStartKeyAlgorithm;
++    sal_Int32 m_nImportedEncryptionAlgorithm;
++    sal_Int32 m_nImportedChecksumAlgorithm;
++    sal_Int32 m_nImportedDerivedKeySize;
++
++    sal_uInt8   m_nStreamMode;
++    sal_uInt32  m_nMagicalHackPos;
++    sal_uInt32  m_nMagicalHackSize;
++
++    sal_Bool m_bHasSeekable;
++
++    sal_Bool m_bCompressedIsSetFromOutside;
++
++    sal_Bool m_bFromManifest;
++
++    bool m_bUseWinEncoding;
++
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnSeekStream();
++
++public:
++    sal_Bool HasOwnKey () const  { return bHaveOwnKey;}
++    sal_Bool IsToBeCompressed () const { return bToBeCompressed;}
++    sal_Bool IsToBeEncrypted () const { return bToBeEncrypted;}
++    sal_Bool IsEncrypted () const    { return bIsEncrypted;}
++    sal_Bool IsPackageMember () const { return m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER;}
++
++    sal_Bool IsFromManifest() const { return m_bFromManifest; }
++    void SetFromManifest( sal_Bool bValue ) { m_bFromManifest = bValue; }
++
++    ::rtl::Reference< EncryptionData > GetEncryptionData( bool bWinEncoding = false );
++    void SetBaseEncryptionData( const ::rtl::Reference< BaseEncryptionData >& xData );
++
++    ::com::sun::star::uno::Sequence< sal_Int8 > GetEncryptionKey( bool bWinEncoding = false );
++
++    sal_Int32 GetStartKeyGenID();
++
++    const com::sun::star::uno::Sequence < sal_Int8 > getInitialisationVector () const
++    { return m_xBaseEncryptionData->m_aInitVector;}
++    const com::sun::star::uno::Sequence < sal_Int8 > getDigest () const
++    { return m_xBaseEncryptionData->m_aDigest;}
++    const com::sun::star::uno::Sequence < sal_Int8 > getSalt () const
++    { return m_xBaseEncryptionData->m_aSalt;}
++    sal_Int32 getIterationCount () const
++    { return m_xBaseEncryptionData->m_nIterationCount;}
++    sal_Int32 getSize () const
++    { return aEntry.nSize;}
++
++    sal_uInt8 GetStreamMode() const { return m_nStreamMode; }
++    sal_uInt32 GetMagicalHackPos() const { return m_nMagicalHackPos; }
++    sal_uInt32 GetMagicalHackSize() const { return m_nMagicalHackSize; }
++    sal_Int32 GetEncryptionAlgorithm() const;
++    sal_Int32 GetBlockSize() const;
++
++    void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
++    void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
++    void SetImportedStartKeyAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedStartKeyAlgorithm = nAlgorithm; }
++    void SetImportedEncryptionAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedEncryptionAlgorithm = nAlgorithm; }
++    void SetImportedChecksumAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedChecksumAlgorithm = nAlgorithm; }
++    void SetImportedDerivedKeySize( sal_Int32 nSize ) { m_nImportedDerivedKeySize = nSize; }
++    void SetToBeEncrypted (sal_Bool bNewValue)
++    {
++        bToBeEncrypted  = bNewValue;
++        if ( bToBeEncrypted && !m_xBaseEncryptionData.is())
++            m_xBaseEncryptionData = new BaseEncryptionData;
++        else if ( !bToBeEncrypted && m_xBaseEncryptionData.is() )
++            m_xBaseEncryptionData.clear();
++    }
++    void SetPackageMember (sal_Bool bNewValue);
++
++    void setKey (const com::sun::star::uno::Sequence < sal_Int8 >& rNewKey )
++    { m_aEncryptionKey = rNewKey; m_aStorageEncryptionKeys.realloc( 0 ); }
++    void setInitialisationVector (const com::sun::star::uno::Sequence < sal_Int8 >& rNewVector )
++    { m_xBaseEncryptionData->m_aInitVector = rNewVector;}
++    void setSalt (const com::sun::star::uno::Sequence < sal_Int8 >& rNewSalt )
++    { m_xBaseEncryptionData->m_aSalt = rNewSalt;}
++    void setDigest (const com::sun::star::uno::Sequence < sal_Int8 >& rNewDigest )
++    { m_xBaseEncryptionData->m_aDigest = rNewDigest;}
++    void setIterationCount (const sal_Int32 nNewCount)
++    { m_xBaseEncryptionData->m_nIterationCount = nNewCount;}
++    void setSize (const sal_Int32 nNewSize);
++
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnStreamNoWrap() { return xStream; }
++
++    void CloseOwnStreamIfAny();
++
++    ZipPackageStream ( ZipPackage & rNewPackage,
++                        const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
++                        sal_Bool bAllowRemoveOnInsert );
++    virtual ~ZipPackageStream( void );
++
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawEncrStreamNoHeaderCopy();
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > TryToGetRawFromDataStream(
++                                                                                    sal_Bool bAddHeaderForEncr );
++
++    sal_Bool ParsePackageRawStream();
++
++    void setZipEntryOnLoading( const ZipEntry &rInEntry);
++    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
++        throw(::com::sun::star::uno::RuntimeException);
++
++    static const ::com::sun::star::uno::Sequence < sal_Int8 >& static_getImplementationId();
++
++    // XActiveDataSink
++    virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
++        throw(::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  )
++        throw(::com::sun::star::uno::RuntimeException);
++
++    // XDataSinkEncrSupport
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream()
++        throw ( ::com::sun::star::packages::WrongPasswordException,
++                ::com::sun::star::io::IOException,
++                ::com::sun::star::uno::RuntimeException );
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream()
++        throw ( ::com::sun::star::packages::NoEncryptionException,
++                ::com::sun::star::io::IOException,
++                ::com::sun::star::uno::RuntimeException );
++    virtual void SAL_CALL setDataStream(
++                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
++        throw ( ::com::sun::star::io::IOException,
++                ::com::sun::star::uno::RuntimeException );
++    virtual void SAL_CALL setRawStream(
++                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
++        throw ( ::com::sun::star::packages::EncryptionNotAllowedException,
++                ::com::sun::star::packages::NoRawFormatException,
++                ::com::sun::star::io::IOException,
++                ::com::sun::star::uno::RuntimeException );
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStream()
++        throw ( ::com::sun::star::io::IOException,
++                ::com::sun::star::uno::RuntimeException );
++
++    // XUnoTunnel
++    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
++        throw(::com::sun::star::uno::RuntimeException);
++
++    // XPropertySet
++    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName )
++        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
++
++    // XServiceInfo
++    virtual ::rtl::OUString SAL_CALL getImplementationName(  )
++        throw (::com::sun::star::uno::RuntimeException);
++    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
++        throw (::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  )
++        throw (::com::sun::star::uno::RuntimeException);
++};
++#endif
+diff --git a/package/qa/storages/TestHelper.java b/package/qa/storages/TestHelper.java
+index 0c1580f..b0b3434 100644
+--- a/package/qa/storages/TestHelper.java
++++ b/package/qa/storages/TestHelper.java
+@@ -1434,24 +1434,24 @@ public class TestHelper  {
+ 
+         try
+         {
+-            byte pData[][] = new byte[1][22];
+-            if ( xHeadRawStream.readBytes( pData, 22 ) != 22 )
++            byte pData[][] = new byte[1][38];
++            if ( xHeadRawStream.readBytes( pData, 38 ) != 38 )
+             {
+                 Error( "Can't read header of encrypted stream '" + sStreamName + "' raw representations!" );
+                 return false;
+             }
+ 
+-            if ( pData[0][0] != 0x4d || pData[0][1] != 0x47 || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
++            if ( pData[0][0] != 0x4d || pData[0][1] != 0x4d || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
+             {
+                 Error( "No signature in the header of encrypted stream '" + sStreamName + "' raw representations!" );
+                 return false;
+             }
+ 
+             int nVariableHeaderLength =
+-                        ( pData[0][14] + pData[0][15] * 0x100 ) // salt length
+-                        + ( pData[0][16] + pData[0][17] * 0x100 ) // iv length
+-                        + ( pData[0][18] + pData[0][19] * 0x100 ) // digest length
+-                        + ( pData[0][20] + pData[0][21] * 0x100 ); // mediatype length
++                        ( pData[0][30] + pData[0][31] * 0x100 ) // salt length
++                        + ( pData[0][32] + pData[0][33] * 0x100 ) // iv length
++                        + ( pData[0][34] + pData[0][35] * 0x100 ) // digest length
++                        + ( pData[0][36] + pData[0][37] * 0x100 ); // mediatype length
+ 
+             xHeadRawStream.skipBytes( nVariableHeaderLength );
+ 
+@@ -1467,7 +1467,7 @@ public class TestHelper  {
+ 
+                 if ( nRead1 != nRead2 )
+                 {
+-                    Error( "The encrypted stream '" + sStreamName + "' raw representations have different size!" );
++                    Error( "The encrypted stream '" + sStreamName + "' raw representations have different size! nRead1 - nRead2 = " + ( new Integer( nRead1 - nRead2 ) ).toString() );
+                     return false;
+                 }
+ 
+diff --git a/package/source/manifest/Base64Codec.cxx b/package/source/manifest/Base64Codec.cxx
+index 1438d86..5dc4ebf 100644
+--- a/package/source/manifest/Base64Codec.cxx
++++ b/package/source/manifest/Base64Codec.cxx
+@@ -131,11 +131,11 @@ void ThreeByteToFourByte (const sal_uInt8* pBuffer, const sal_Int32 nStart, cons
+     sBuffer.setCharAt(3, aBase64EncodeTable [nIndex]);
+ }
+ 
+-void Base64Codec::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence < sal_uInt8 >& aPass)
++void Base64Codec::encodeBase64(rtl::OUStringBuffer& aStrBuffer, const uno::Sequence < sal_Int8 >& aPass)
+ {
+     sal_Int32 i(0);
+     sal_Int32 nBufferLength(aPass.getLength());
+-    const sal_uInt8* pBuffer = aPass.getConstArray();
++    const sal_uInt8* pBuffer = reinterpret_cast< const sal_uInt8* >( aPass.getConstArray() );
+     while (i < nBufferLength)
+     {
+         rtl::OUStringBuffer sBuffer;
+@@ -185,7 +185,7 @@ void FourByteToThreeByte (sal_uInt8* pBuffer, sal_Int32& nLength, const sal_Int3
+     pBuffer[nStart + 2] = OneByte;
+ }
+ 
+-void Base64Codec::decodeBase64(uno::Sequence< sal_uInt8 >& aBuffer, const rtl::OUString& sBuffer)
++void Base64Codec::decodeBase64(uno::Sequence< sal_Int8 >& aBuffer, const rtl::OUString& sBuffer)
+ {
+     sal_Int32 nFirstLength((sBuffer.getLength() / 4) * 3);
+     sal_uInt8* pBuffer = new sal_uInt8[nFirstLength];
+@@ -201,7 +201,7 @@ void Base64Codec::decodeBase64(uno::Sequence< sal_uInt8 >& aBuffer, const rtl::O
+         i += 4;
+         k += 3;
+     }
+-    aBuffer = uno::Sequence<sal_uInt8>(pBuffer, nSecondLength);
++    aBuffer = uno::Sequence<sal_Int8>( reinterpret_cast< sal_Int8* >( pBuffer ), nSecondLength );
+     delete[] pBuffer;
+ }
+ 
+diff --git a/package/source/manifest/Base64Codec.hxx b/package/source/manifest/Base64Codec.hxx
+index 941c115..60456ad 100644
+--- a/package/source/manifest/Base64Codec.hxx
++++ b/package/source/manifest/Base64Codec.hxx
+@@ -40,8 +40,8 @@ class OUStringBuffer;
+ class Base64Codec
+ {
+ public:
+-    static void encodeBase64(rtl::OUStringBuffer& aStrBuffer, const com::sun::star::uno::Sequence<sal_uInt8>& aPass);
+-    static void decodeBase64(com::sun::star::uno::Sequence<sal_uInt8>& aPass, const rtl::OUString& sBuffer);
++    static void encodeBase64(rtl::OUStringBuffer& aStrBuffer, const com::sun::star::uno::Sequence<sal_Int8>& aPass);
++    static void decodeBase64(com::sun::star::uno::Sequence<sal_Int8>& aPass, const rtl::OUString& sBuffer);
+ };
+ #endif
+ 
+diff --git a/package/source/manifest/ManifestDefines.hxx b/package/source/manifest/ManifestDefines.hxx
+index 67159ee..dc9c47e 100644
+--- a/package/source/manifest/ManifestDefines.hxx
++++ b/package/source/manifest/ManifestDefines.hxx
+@@ -65,6 +65,26 @@
+ #define CHECKSUM_TYPE "SHA1/1K"
+ #define DERIVED_KEY_SIZE "16"
+ 
++#define SHA256_URL "http://www.w3.org/2001/04/xmlenc#sha256"
++//http://tools.oasis-open.org/issues/browse/OFFICE-3702
++//http://tools.oasis-open.org/issues/browse/OFFICE-3708
++#define SHA256_URL_TYPO "http://www.w3.org/2000/09/xmldsig#sha256"
++#define SHA1_NAME "SHA1"
++#define SHA1_URL "http://www.w3.org/2000/09/xmldsig#sha1"
++
++#define SHA1_1K_NAME "SHA1/1K"
++#define SHA1_1K_URL "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#sha1-1k"
++#define SHA256_1K_URL "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#sha256-1k"
++
++#define BLOWFISH_NAME "Blowfish CFB"
++#define BLOWFISH_URL "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#blowfish"
++#define AES128_URL "http://www.w3.org/2001/04/xmlenc#aes128-cbc"
++#define AES192_URL "http://www.w3.org/2001/04/xmlenc#aes192-cbc"
++#define AES256_URL "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
++
++#define PBKDF2_NAME "PBKDF2"
++#define PBKDF2_URL "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#pbkdf2"
++
+ #endif
+ 
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx
+index dfdcf2f..bb53541 100644
+--- a/package/source/manifest/ManifestExport.cxx
++++ b/package/source/manifest/ManifestExport.cxx
+@@ -239,7 +239,7 @@ ManifestExport::ManifestExport(Reference < XDocumentHandler > xHandler,  const S
+             ::comphelper::AttributeList * pNewAttrList = new ::comphelper::AttributeList;
+             Reference < XAttributeList > xNewAttrList (pNewAttrList);
+             OUStringBuffer aBuffer;
+-            Sequence < sal_uInt8 > aSequence;
++            Sequence < sal_Int8 > aSequence;
+ 
+             xHandler->ignorableWhitespace ( sWhiteSpace );
+             if ( pDigest )
+diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx
+index 2f99d66..abd67d5 100644
+--- a/package/source/manifest/ManifestImport.cxx
++++ b/package/source/manifest/ManifestImport.cxx
+@@ -32,6 +32,8 @@
+ #include <ManifestDefines.hxx>
+ #include <Base64Codec.hxx>
+ #include <com/sun/star/xml/sax/XAttributeList.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
+ #include <com/sun/star/beans/PropertyValue.hpp>
+ 
+ using namespace com::sun::star::uno;
+@@ -45,12 +47,14 @@ using ::rtl::OUString;
+ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
+ : nNumProperty ( 0 )
+ , bIgnoreEncryptData 	( sal_False )
++, nDerivedKeySize( 0 )
+ , rManVector ( rNewManVector )
+ 
+ , sFileEntryElement   	( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY ) )
+ , sManifestElement    	( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) )
+ , sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) )
+ , sAlgorithmElement	( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) )
++, sStartKeyAlgElement 	( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_START_KEY_GENERATION ) )
+ , sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) )
+ 
+ , sCdataAttribute     			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
+@@ -61,7 +65,9 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV
+ , sSaltAttribute 				( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) )
+ , sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) )
+ , sIterationCountAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
++, sKeySizeAttribute             ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) )
+ , sAlgorithmNameAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
++, sStartKeyAlgNameAttribute     ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) )
+ , sKeyDerivationNameAttribute 	( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
+ , sChecksumAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
+ , sChecksumTypeAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
+@@ -70,15 +76,34 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV
+ , sMediaTypeProperty 			( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) )
+ , sVersionProperty  			( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) )
+ , sIterationCountProperty 		( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) )
++, sDerivedKeySizeProperty		( RTL_CONSTASCII_USTRINGPARAM ( "DerivedKeySize" ) )
+ , sSaltProperty 				( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) )
+ , sInitialisationVectorProperty	( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) )
+ , sSizeProperty 				( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) )
+ , sDigestProperty 				( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) )
++, sEncryptionAlgProperty		( RTL_CONSTASCII_USTRINGPARAM ( "EncryptionAlgorithm" ) )
++, sStartKeyAlgProperty 			( RTL_CONSTASCII_USTRINGPARAM ( "StartKeyAlgorithm" ) )
++, sDigestAlgProperty 			( RTL_CONSTASCII_USTRINGPARAM ( "DigestAlgorithm" ) )
+ 
+ , sWhiteSpace 					( RTL_CONSTASCII_USTRINGPARAM ( " " ) )
+-, sBlowfish						( RTL_CONSTASCII_USTRINGPARAM ( "Blowfish CFB" ) )
+-, sPBKDF2 						( RTL_CONSTASCII_USTRINGPARAM ( "PBKDF2" ) )
+-, sChecksumType					( RTL_CONSTASCII_USTRINGPARAM ( CHECKSUM_TYPE ) )
++
++, sSHA256_URL  					( RTL_CONSTASCII_USTRINGPARAM ( SHA256_URL ) )
++, sSHA256_URL_TYPO              ( RTL_CONSTASCII_USTRINGPARAM ( SHA256_URL_TYPO ) )
++, sSHA1_Name	    			( RTL_CONSTASCII_USTRINGPARAM ( SHA1_NAME ) )
++, sSHA1_URL	    				( RTL_CONSTASCII_USTRINGPARAM ( SHA1_URL ) )
++
++, sSHA256_1k_URL				( RTL_CONSTASCII_USTRINGPARAM ( SHA256_1K_URL ) )
++, sSHA1_1k_Name					( RTL_CONSTASCII_USTRINGPARAM ( SHA1_1K_NAME ) )
++, sSHA1_1k_URL 					( RTL_CONSTASCII_USTRINGPARAM ( SHA1_1K_URL ) )
++
++, sBlowfish_Name				( RTL_CONSTASCII_USTRINGPARAM ( BLOWFISH_NAME ) )
++, sBlowfish_URL					( RTL_CONSTASCII_USTRINGPARAM ( BLOWFISH_URL ) )
++, sAES128_URL                   ( RTL_CONSTASCII_USTRINGPARAM ( AES128_URL ) )
++, sAES192_URL                   ( RTL_CONSTASCII_USTRINGPARAM ( AES192_URL ) )
++, sAES256_URL                   ( RTL_CONSTASCII_USTRINGPARAM ( AES256_URL ) )
++
++, sPBKDF2_Name					( RTL_CONSTASCII_USTRINGPARAM ( PBKDF2_NAME ) )
++, sPBKDF2_URL					( RTL_CONSTASCII_USTRINGPARAM ( PBKDF2_URL ) )
+ {
+     aStack.reserve( 10 );
+ }
+@@ -143,43 +168,90 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
+             if ( aConvertedName.equals( sEncryptionDataElement ) )
+             {
+                 // If this element exists, then this stream is encrypted and we need
+-                // to store the initialisation vector, salt and iteration count used
++                // to import the initialisation vector, salt and iteration count used
++                nDerivedKeySize = 0;
+                 OUString aString = aConvertedAttribs[sChecksumTypeAttribute];
+-                if ( aString == sChecksumType && !bIgnoreEncryptData )
++                if ( !bIgnoreEncryptData )
++                {
++                    if ( aString.equals( sSHA1_1k_Name ) || aString.equals( sSHA1_1k_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sDigestAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1_1K;
++                    }
++                    else if ( aString.equals( sSHA256_1k_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sDigestAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256_1K;
++                    }
++                    else
++                        bIgnoreEncryptData = sal_True;
++
++                    if ( !bIgnoreEncryptData )
+                 {
+                     aString = aConvertedAttribs[sChecksumAttribute];
+-                    Sequence < sal_uInt8 > aDecodeBuffer;
++                    Sequence < sal_Int8 > aDecodeBuffer;
+                     Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+                     aSequence[nNumProperty].Name = sDigestProperty;
+                     aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+                 }
+             }
+         }
++        }
+         else if ( aIter->m_aConvertedName.equals( sEncryptionDataElement ) )
+         {
+             if ( aConvertedName == sAlgorithmElement )
+             {
++                if ( !bIgnoreEncryptData )
++                {
+                 OUString aString = aConvertedAttribs[sAlgorithmNameAttribute];
+-                if ( aString == sBlowfish && !bIgnoreEncryptData )
++                    if ( aString.equals( sBlowfish_Name ) || aString.equals( sBlowfish_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sEncryptionAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8;
++                    }
++                    else if ( aString.equals( sAES256_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sEncryptionAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
++                        OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" );
++                        nDerivedKeySize = 32;
++                    }
++                    else if ( aString.equals( sAES192_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sEncryptionAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
++                        OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" );
++                        nDerivedKeySize = 24;
++                    }
++                    else if ( aString.equals( sAES128_URL ) )
++                    {
++                        aSequence[nNumProperty].Name = sEncryptionAlgProperty;
++                        aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
++                        OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" );
++                        nDerivedKeySize = 16;
++                    }
++                    else
++                        bIgnoreEncryptData = sal_True;
++
++                    if ( !bIgnoreEncryptData )
+                 {
+                     aString = aConvertedAttribs[sInitialisationVectorAttribute];
+-                    Sequence < sal_uInt8 > aDecodeBuffer;
++                    Sequence < sal_Int8 > aDecodeBuffer;
+                     Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+                     aSequence[nNumProperty].Name = sInitialisationVectorProperty;
+                     aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+                 }
+-                else
+-                    // If we don't recognise the algorithm, then the key derivation info
+-                    // is useless to us
+-                    bIgnoreEncryptData = sal_True;
++                }
+             }
+             else if ( aConvertedName == sKeyDerivationElement )
+             {
++                if ( !bIgnoreEncryptData )
++                {
+                 OUString aString = aConvertedAttribs[sKeyDerivationNameAttribute];
+-                if ( aString == sPBKDF2 && !bIgnoreEncryptData )
++                    if ( aString.equals( sPBKDF2_Name ) || aString.equals( sPBKDF2_URL ) )
+                 {
+                     aString = aConvertedAttribs[sSaltAttribute];
+-                    Sequence < sal_uInt8 > aDecodeBuffer;
++                    Sequence < sal_Int8 > aDecodeBuffer;
+                     Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
+                     aSequence[nNumProperty].Name = sSaltProperty;
+                     aSequence[nNumProperty++].Value <<= aDecodeBuffer;
+@@ -187,10 +259,40 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
+                     aString = aConvertedAttribs[sIterationCountAttribute];
+                     aSequence[nNumProperty].Name = sIterationCountProperty;
+                     aSequence[nNumProperty++].Value <<= aString.toInt32();
++
++                        aString = aConvertedAttribs[sKeySizeAttribute];
++                        if ( aString.getLength() )
++                        {
++                            sal_Int32 nKey = aString.toInt32();
++                            OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" );
++                            nDerivedKeySize = nKey;
++                        }
++                        else if ( !nDerivedKeySize )
++                            nDerivedKeySize = 16;
++                        else if ( nDerivedKeySize != 16 )
++                            OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" );
++
++                        aSequence[nNumProperty].Name = sDerivedKeySizeProperty;
++                        aSequence[nNumProperty++].Value <<= nDerivedKeySize;
++                }
++                else
++                        bIgnoreEncryptData = sal_True;
++                }
++            }
++            else if ( aConvertedName == sStartKeyAlgElement )
++            {
++                OUString aString = aConvertedAttribs[sStartKeyAlgNameAttribute];
++                if (aString.equals(sSHA256_URL) || aString.equals(sSHA256_URL_TYPO))
++                {
++                    aSequence[nNumProperty].Name = sStartKeyAlgProperty;
++                    aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256;
++                }
++                else if ( aString.equals( sSHA1_Name ) || aString.equals( sSHA1_URL ) )
++                {
++                    aSequence[nNumProperty].Name = sStartKeyAlgProperty;
++                    aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1;
+                 }
+                 else
+-                    // If we don't recognise the key derivation technique, then the
+-                    // algorithm info is useless to us
+                     bIgnoreEncryptData = sal_True;
+             }
+         }
+diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx
+index 9655e71..4b92797 100644
+--- a/package/source/manifest/ManifestImport.hxx
++++ b/package/source/manifest/ManifestImport.hxx
+@@ -65,12 +65,14 @@ protected:
+     sal_Int16 		nNumProperty;
+     ManifestStack aStack;
+     sal_Bool bIgnoreEncryptData;
++    sal_Int32 nDerivedKeySize;
+     ::std::vector < ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > > & rManVector;
+ 
+     const ::rtl::OUString sFileEntryElement;
+     const ::rtl::OUString sManifestElement;
+     const ::rtl::OUString sEncryptionDataElement;
+     const ::rtl::OUString sAlgorithmElement;
++    const ::rtl::OUString sStartKeyAlgElement;
+     const ::rtl::OUString sKeyDerivationElement;
+ 
+     const ::rtl::OUString sCdataAttribute;
+@@ -81,7 +83,9 @@ protected:
+     const ::rtl::OUString sSaltAttribute;
+     const ::rtl::OUString sInitialisationVectorAttribute;
+     const ::rtl::OUString sIterationCountAttribute;
++    const ::rtl::OUString sKeySizeAttribute;
+     const ::rtl::OUString sAlgorithmNameAttribute;
++    const ::rtl::OUString sStartKeyAlgNameAttribute;
+     const ::rtl::OUString sKeyDerivationNameAttribute;
+     const ::rtl::OUString sChecksumAttribute;
+     const ::rtl::OUString sChecksumTypeAttribute;
+@@ -90,15 +94,34 @@ protected:
+     const ::rtl::OUString sMediaTypeProperty;
+     const ::rtl::OUString sVersionProperty;
+     const ::rtl::OUString sIterationCountProperty;
++    const ::rtl::OUString sDerivedKeySizeProperty;
+     const ::rtl::OUString sSaltProperty;
+     const ::rtl::OUString sInitialisationVectorProperty;
+     const ::rtl::OUString sSizeProperty;
+     const ::rtl::OUString sDigestProperty;
++    const ::rtl::OUString sEncryptionAlgProperty;
++    const ::rtl::OUString sStartKeyAlgProperty;
++    const ::rtl::OUString sDigestAlgProperty;
+ 
+     const ::rtl::OUString sWhiteSpace;
+-    const ::rtl::OUString sBlowfish;
+-    const ::rtl::OUString sPBKDF2;
+-    const ::rtl::OUString sChecksumType;
++
++    const ::rtl::OUString sSHA256_URL;
++    const ::rtl::OUString sSHA256_URL_TYPO;
++    const ::rtl::OUString sSHA1_Name;
++    const ::rtl::OUString sSHA1_URL;
++
++    const ::rtl::OUString sSHA256_1k_URL;
++    const ::rtl::OUString sSHA1_1k_Name;
++    const ::rtl::OUString sSHA1_1k_URL;
++
++    const ::rtl::OUString sBlowfish_Name;
++    const ::rtl::OUString sBlowfish_URL;
++    const ::rtl::OUString sAES128_URL;
++    const ::rtl::OUString sAES192_URL;
++    const ::rtl::OUString sAES256_URL;
++
++    const ::rtl::OUString sPBKDF2_Name;
++    const ::rtl::OUString sPBKDF2_URL;
+ 
+ 
+     ::rtl::OUString PushNameAndNamespaces( const ::rtl::OUString& aName,
+diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx
+index c1c5e8f..03e1776 100644
+--- a/package/source/xstor/owriteablestream.cxx
++++ b/package/source/xstor/owriteablestream.cxx
+@@ -47,6 +47,8 @@
+ #include <comphelper/storagehelper.hxx>
+ #include <comphelper/ofopxmlhelper.hxx>
+ 
++#include <PackageConstants.hxx>
++
+ #include "selfterminatefilestream.hxx"
+ #include "owriteablestream.hxx"
+ #include "oseekinstream.hxx"
+@@ -111,15 +113,14 @@ namespace
+ {
+ //-----------------------------------------------
+ void SetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySet >& xPropertySet,
+-                                    const uno::Sequence< sal_Int8 >& aKey )
++                                    const uno::Sequence< beans::NamedValue >& aKey )
+ {
+     OSL_ENSURE( xPropertySet.is(), "No property set is provided!\n" );
+     if ( !xPropertySet.is() )
+         throw uno::RuntimeException();
+ 
+-    ::rtl::OUString aString_EncryptionKey (RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") );
+     try {
+-        xPropertySet->setPropertyValue( aString_EncryptionKey, uno::makeAny( aKey ) );
++        xPropertySet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ), uno::makeAny( aKey ) );
+     }
+     catch ( uno::Exception& aException )
+     {
+@@ -137,9 +138,8 @@ uno::Any GetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySe
+     if ( !xPropertySet.is() )
+         throw uno::RuntimeException();
+ 
+-    ::rtl::OUString aString_EncryptionKey (RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") );
+     try {
+-        return xPropertySet->getPropertyValue( aString_EncryptionKey );
++        return xPropertySet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) );
+     }
+     catch ( uno::Exception& aException )
+     {
+@@ -152,16 +152,65 @@ uno::Any GetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySe
+ }
+ 
+ //-----------------------------------------------
+-sal_Bool SequencesEqual( uno::Sequence< sal_Int8 > aSequence1, uno::Sequence< sal_Int8 > aSequence2 )
++bool SequencesEqual( const uno::Sequence< sal_Int8 >& aSequence1, const uno::Sequence< sal_Int8 >& aSequence2 )
+ {
+     if ( aSequence1.getLength() != aSequence2.getLength() )
+-        return sal_False;
++        return false;
+ 
+     for ( sal_Int32 nInd = 0; nInd < aSequence1.getLength(); nInd++ )
+         if ( aSequence1[nInd] != aSequence2[nInd] )
+-            return sal_False;
++            return false;
++
++    return true;
++}
++
++//-----------------------------------------------
++bool SequencesEqual( const uno::Sequence< beans::NamedValue >& aSequence1, const uno::Sequence< beans::NamedValue >& aSequence2 )
++{
++    if ( aSequence1.getLength() != aSequence2.getLength() )
++        return false;
++
++    for ( sal_Int32 nInd = 0; nInd < aSequence1.getLength(); nInd++ )
++    {
++        bool bHasMember = false;
++        uno::Sequence< sal_Int8 > aMember1;
++        sal_Int32 nMember1 = 0;
++        if ( ( aSequence1[nInd].Value >>= aMember1 ) )
++        {
++            for ( sal_Int32 nInd2 = 0; nInd2 < aSequence2.getLength(); nInd2++ )
++            {
++                if ( aSequence1[nInd].Name.equals( aSequence2[nInd2].Name ) )
++                {
++                    bHasMember = true;
++
++                    uno::Sequence< sal_Int8 > aMember2;
++                    if ( !( aSequence2[nInd2].Value >>= aMember2 ) || !SequencesEqual( aMember1, aMember2 ) )
++                        return false;
++                }
++            }
++        }
++        else if ( ( aSequence1[nInd].Value >>= nMember1 ) )
++        {
++            for ( sal_Int32 nInd2 = 0; nInd2 < aSequence2.getLength(); nInd2++ )
++            {
++                if ( aSequence1[nInd].Name.equals( aSequence2[nInd2].Name ) )
++                {
++                    bHasMember = true;
+ 
+-    return sal_True;
++                    sal_Int32 nMember2 = 0;
++                    if ( !( aSequence2[nInd2].Value >>= nMember2 ) || nMember1 != nMember2 )
++                        return false;
++                }
++            }
++        }
++        else
++            return false;
++
++        if ( !bHasMember )
++            return false;
++    }
++
++    return true;
+ }
+ 
+ //-----------------------------------------------
+@@ -395,7 +444,7 @@ sal_Bool OWriteStream_Impl::IsEncrypted()
+ 
+     // since a new key set to the package stream it should not be removed except the case when
+     // the stream becomes nonencrypted
+-    uno::Sequence< sal_Int8 > aKey;
++    uno::Sequence< beans::NamedValue > aKey;
+     if ( bToBeEncr )
+         GetEncryptionKeyProperty_Impl( xPropSet ) >>= aKey;
+ 
+@@ -822,8 +871,8 @@ void OWriteStream_Impl::InsertStreamDirectly( const uno::Reference< io::XInputSt
+             throw uno::RuntimeException();
+ 
+         // set to be encrypted but do not use encryption key
+-        xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") ),
+-                                        uno::makeAny( uno::Sequence< sal_Int8 >() ) );
++        xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( STORAGE_ENCRYPTION_KEYS_PROPERTY ),
++                                        uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
+         xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Encrypted") ),
+                                         uno::makeAny( sal_True ) );
+     }
+@@ -921,8 +970,8 @@ void OWriteStream_Impl::Commit()
+             throw uno::RuntimeException();
+ 
+         // set to be encrypted but do not use encryption key
+-        xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") ),
+-                                        uno::makeAny( uno::Sequence< sal_Int8 >() ) );
++        xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( STORAGE_ENCRYPTION_KEYS_PROPERTY ),
++                                        uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
+         xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Encrypted") ),
+                                         uno::makeAny( sal_True ) );
+     }
+@@ -931,8 +980,8 @@ void OWriteStream_Impl::Commit()
+         if ( m_nStorageType != embed::StorageFormats::PACKAGE )
+             throw uno::RuntimeException();
+ 
+-        xPropertySet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") ),
+-                                        uno::makeAny( m_aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1UTF8, uno::Sequence< sal_Int8 >() ) ) );
++        xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( STORAGE_ENCRYPTION_KEYS_PROPERTY ),
++                                        uno::makeAny( m_aEncryptionData.getAsConstNamedValueList() ) );
+     }
+ 
+     // the stream should be free soon, after package is stored
+@@ -1265,7 +1314,7 @@ uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMod
+     }
+     else
+     {
+-        SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1UTF8, uno::Sequence< sal_Int8 >() ) );
++        SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
+ 
+         try {
+             xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
+@@ -1274,32 +1323,9 @@ uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMod
+             m_bHasCachedEncryptionData = sal_True;
+             m_aEncryptionData = aEncryptionData;
+         }
+-        catch( packages::WrongPasswordException& )
+-        {
+-            // retry with different encoding
+-            SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1MS1252, uno::Sequence< sal_Int8 >() ) );
+-            try {
+-                // the stream must be cashed to be resaved
+-                xResultStream = GetStream_Impl( nStreamMode | embed::ElementModes::SEEKABLE, bHierarchyAccess );
+-
+-                m_bUseCommonEncryption = sal_False; // very important to set it to false
+-                m_bHasCachedEncryptionData = sal_True;
+-                m_aEncryptionData = aEncryptionData;
+-
+-                // the stream must be resaved with new password encryption
+-                if ( nStreamMode & embed::ElementModes::WRITE )
+-                {
+-                    FillTempGetFileName();
+-                    m_bHasDataToFlush = sal_True;
+-
+-                    // TODO/LATER: should the notification be done?
+-                    if ( m_pParent )
+-                        m_pParent->m_bIsModified = sal_True;
+-                }
+-            }
+             catch( packages::WrongPasswordException& aWrongPasswordException )
+             {
+-                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
++                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
+                 AddLog( aWrongPasswordException.Message );
+                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+                 throw;
+@@ -1310,20 +1336,10 @@ uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMod
+                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
+ 
+                 OSL_FAIL( "Can't write encryption related properties!\n" );
+-                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
++                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
+                 throw io::IOException(); // TODO:
+             }
+         }
+-        catch( uno::Exception& aException )
+-        {
+-            SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+-
+-            AddLog( aException.Message );
+-            AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+-            throw;
+-        }
+-
+-    }
+ 
+     OSL_ENSURE( xResultStream.is(), "In case stream can not be retrieved an exception must be thrown!\n" );
+ 
+@@ -1625,8 +1641,7 @@ void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTar
+     {
+         // TODO: introduce last commited cashed password information and use it here
+         // that means "use common pass" also should be remembered on flash
+-        uno::Sequence< sal_Int8 > aNewKey = aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1UTF8, uno::Sequence< sal_Int8 >() );
+-        uno::Sequence< sal_Int8 > aOldKey = aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1MS1252, uno::Sequence< sal_Int8 >() );
++        uno::Sequence< beans::NamedValue > aKey = aEncryptionData.getAsConstNamedValueList();
+ 
+         uno::Reference< beans::XPropertySet > xProps( m_xPackageStream, uno::UNO_QUERY );
+         if ( !xProps.is() )
+@@ -1637,9 +1652,9 @@ void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTar
+         if ( !bEncr )
+             throw packages::NoEncryptionException();
+ 
+-        uno::Sequence< sal_Int8 > aEncrKey;
+-        xProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EncryptionKey") ) ) >>= aEncrKey;
+-        if ( !SequencesEqual( aNewKey, aEncrKey ) && !SequencesEqual( aOldKey, aEncrKey ) )
++        uno::Sequence< beans::NamedValue > aPackKey;
++        xProps->getPropertyValue( ::rtl::OUString::createFromAscii( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) >>= aPackKey;
++        if ( !SequencesEqual( aKey, aPackKey ) )
+             throw packages::WrongPasswordException();
+ 
+         // the correct key must be set already
+@@ -1648,7 +1663,7 @@ void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTar
+     else
+     {
+         uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
+-        SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1UTF8, uno::Sequence< sal_Int8 >() ) );
++        SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
+ 
+         try {
+             xDataToCopy = m_xPackageStream->getDataStream();
+@@ -1656,42 +1671,19 @@ void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTar
+             if ( !xDataToCopy.is() )
+             {
+                 OSL_FAIL( "Encrypted ZipStream must already have input stream inside!\n" );
+-                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+-            }
+-        }
+-        catch( packages::WrongPasswordException& aWrongPasswordException )
+-        {
+-            SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1MS1252, uno::Sequence< sal_Int8 >() ) );
+-            try {
+-                xDataToCopy = m_xPackageStream->getDataStream();
+-
+-                if ( !xDataToCopy.is() )
+-                {
+-                    OSL_FAIL( "Encrypted ZipStream must already have input stream inside!\n" );
+-                    SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+-                    AddLog( aWrongPasswordException.Message );
+-                    AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+-                    throw;
++            SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
+                 }
+             }
+             catch( uno::Exception& aException )
+             {
+-                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
++                OSL_FAIL( "Can't open encrypted stream!" );
++                SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
+                 AddLog( aException.Message );
+                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+                 throw;
+             }
+-        }
+-        catch( uno::Exception& aException )
+-        {
+-            OSL_FAIL( "Can't open encrypted stream!\n" );
+-            SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
+-            AddLog( aException.Message );
+-            AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
+-            throw;
+-        }
+ 
+-        SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< sal_Int8 >() );
++        SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
+     }
+ 
+     // in case of new inserted package stream it is possible that input stream still was not set
+diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx
+index ab3c5f3..1eca31c 100644
+--- a/package/source/xstor/xstorage.cxx
++++ b/package/source/xstor/xstorage.cxx
+@@ -46,6 +46,7 @@
+ #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+ #include <com/sun/star/beans/NamedValue.hpp>
+ 
++#include <PackageConstants.hxx>
+ 
+ #include <cppuhelper/typeprovider.hxx>
+ #include <cppuhelper/exc_hlp.hxx>
+@@ -572,7 +573,7 @@ void OStorage_Impl::GetStorageProperties()
+         if ( !m_bControlMediaType )
+         {
+             uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
+-            xPackageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) >>= m_bMTFallbackUsed;
++            xPackageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MEDIATYPE_FALLBACK_USED_PROPERTY ) ) ) >>= m_bMTFallbackUsed;
+ 
+             xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= m_aMediaType;
+             m_bControlMediaType = sal_True;
+@@ -750,9 +751,17 @@ void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDes
+         {
+             try
+             {
+-                uno::Reference< embed::XEncryptionProtectedSource2 > xEncr( xDest, uno::UNO_QUERY );
++                uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xDest, uno::UNO_QUERY );
+                 if ( xEncr.is() )
++                {
+                     xEncr->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
++
++                    uno::Sequence< beans::NamedValue > aAlgorithms;
++                    uno::Reference< beans::XPropertySet > xPackPropSet( m_xPackage, uno::UNO_QUERY_THROW );
++                    xPackPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) )
++                        >>= aAlgorithms;
++                    xEncr->setEncryptionAlgorithms( aAlgorithms );
++                }
+             }
+             catch( packages::NoEncryptionException& aNoEncryptionException )
+             {
+@@ -985,7 +994,9 @@ void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
+                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
+ 
+                 // If the common storage password does not allow to open the stream
+-                // it must be copyed in raw way
++                // it could be copyed in raw way, the problem is that the StartKey should be the same
++                // in the ODF1.2 package, so an invalid package could be produced if the stream
++                // is copied from ODF1.1 package, where it is allowed to have different StartKeys
+                 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
+                 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
+                 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
+@@ -2278,7 +2289,8 @@ uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
+                         (	rType
+                         ,	static_cast<embed::XStorageRawAccess*> ( this )
+                         ,	static_cast<embed::XEncryptionProtectedSource*> ( this )
+-                        ,	static_cast<embed::XEncryptionProtectedSource2*> ( this ) );
++                        ,	static_cast<embed::XEncryptionProtectedSource2*> ( this )
++                        ,	static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
+         }
+         else
+         {
+@@ -2338,6 +2350,7 @@ uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
+                                     ,	::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
+                                     ,	::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
+                                     ,	::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
++                                    ,	::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedStorage >* )NULL )
+                                     ,	::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource2 >* )NULL )
+                                     ,	::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
+                                     ,	::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
+@@ -4697,18 +4710,23 @@ void SAL_CALL OStorage::removeEncryption()
+         // TODO: check if the password is valid
+         // update all streams that was encrypted with old password
+ 
+-        uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
+-        if ( !xPackPropSet.is() )
+-            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+-
++        uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
+         try
+         {
+-            xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ),
+-                                            uno::makeAny( uno::Sequence< sal_Int8 >() ) );
++            xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
++                                            uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
+ 
+             m_pImpl->m_bHasCommonEncryptionData = sal_False;
+             m_pImpl->m_aCommonEncryptionData.clear();
+         }
++        catch( uno::RuntimeException& aRException )
++        {
++            m_pImpl->AddLog( aRException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++
++            OSL_FAIL( "The call must not fail, it is pretty simple!" );
++            throw;
++        }
+         catch( uno::Exception& aException )
+         {
+             m_pImpl->AddLog( aException.Message );
+@@ -4767,16 +4785,13 @@ void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValu
+                                                                                     uno::UNO_QUERY ),
+                                                 aCaught );
+         }
+-        
+-        uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
+-        if ( !xPackPropSet.is() )
+-            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
++        uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
+         try
+         {
+             ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
+-            xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ),
+-                                            uno::makeAny( aEncryptionMap.getUnpackedValueOrDefault( PACKAGE_ENCRYPTIONDATA_SHA1UTF8, uno::Sequence< sal_Int8 >() ) ) );
++            xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
++                                            uno::makeAny( aEncryptionMap.getAsConstNamedValueList() ) );
+ 
+             m_pImpl->m_bHasCommonEncryptionData = sal_True;
+             m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
+@@ -4792,6 +4807,82 @@ void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValu
+ 
+ }
+ 
++//____________________________________________________________________________________________________
++//  XEncryptionProtectedStorage
++//____________________________________________________________________________________________________
++
++//-----------------------------------------------
++void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
++    throw (lang::IllegalArgumentException, uno::RuntimeException)
++{
++    RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionAlgorithms" );
++
++    ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
++
++    if ( !m_pImpl )
++    {
++        ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
++        throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
++    }
++
++    if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
++        throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
++
++    if ( !aAlgorithms.getLength() )
++        throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected empty encryption algorithms list!") ), uno::Reference< uno::XInterface >() );
++
++    OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionAlgorithms() method is not available for nonroot storages!\n" );
++    if ( m_pData->m_bIsRoot )
++    {
++        try {
++            m_pImpl->ReadContents();
++        }
++        catch ( uno::RuntimeException& aRuntimeException )
++        {
++            m_pImpl->AddLog( aRuntimeException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++            throw;
++        }
++        catch ( uno::Exception& aException )
++        {
++            m_pImpl->AddLog( aException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++
++            uno::Any aCaught( ::cppu::getCaughtException() );
++            throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
++                                                uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
++                                                                                    uno::UNO_QUERY ),
++                                                aCaught );
++        }
++
++        uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
++        try
++        {
++            xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ),
++                                            uno::makeAny( aAlgorithms ) );
++        }
++        catch ( uno::RuntimeException& aRuntimeException )
++        {
++            m_pImpl->AddLog( aRuntimeException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++            throw;
++        }
++        catch( lang::IllegalArgumentException& aIAException )
++        {
++            m_pImpl->AddLog( aIAException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++
++            throw;
++        }
++        catch( uno::Exception& aException )
++        {
++            m_pImpl->AddLog( aException.Message );
++            m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
++
++            throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
++        }
++    }
++}
+ 
+ //____________________________________________________________________________________________________
+ //	XPropertySet
+@@ -4864,13 +4955,13 @@ void SAL_CALL OStorage::setPropertyValue( const ::rtl::OUString& aPropertyName,
+                 m_pImpl->m_bIsModified = sal_True;
+             }
+         }
+-        else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) )
+-                                    || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasNonEncryptedEntries" ) )
+-                                    || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsInconsistent" ) )
++        else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
++                                    || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
++                                    || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY )
+                                     || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "URL" ) )
+                                     || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "RepairPackage" ) ) ) )
+            || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsRoot" ) )
+-           || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaTypeFallbackUsed" ) ) )
++           || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY ) )
+             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+         else
+             throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+@@ -4944,7 +5035,7 @@ uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyNa
+ 
+     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+       && ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) )
+-        || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaTypeFallbackUsed" ) )
++        || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY )
+         || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Version" ) ) ) )
+     {
+         try
+@@ -5001,9 +5092,9 @@ uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyNa
+             return uno::makeAny( sal_False ); // RepairPackage
+         }
+         else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
+-          && ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) )
+-            || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasNonEncryptedEntries" ) )
+-            || aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsInconsistent" ) ) ) )
++          && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
++            || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
++            || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY ) ) )
+         {
+             try {
+                 m_pImpl->ReadContents();
+diff --git a/package/source/xstor/xstorage.hxx b/package/source/xstor/xstorage.hxx
+index 66a626e..46764df 100644
+--- a/package/source/xstor/xstorage.hxx
++++ b/package/source/xstor/xstorage.hxx
+@@ -37,7 +37,7 @@
+ #include <com/sun/star/embed/XTransactedObject.hpp>
+ #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+ #include <com/sun/star/embed/XClassifiedObject.hpp>
+-#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
++#include <com/sun/star/embed/XEncryptionProtectedStorage.hpp>
+ #include <com/sun/star/embed/XRelationshipAccess.hpp>
+ #include <com/sun/star/util/XModifiable.hpp>
+ #include <com/sun/star/container/XNameAccess.hpp>
+@@ -297,7 +297,7 @@ class OStorage	: public ::com::sun::star::lang::XTypeProvider
+                 , public ::com::sun::star::embed::XTransactedObject
+                 , public ::com::sun::star::embed::XTransactionBroadcaster
+                 , public ::com::sun::star::util::XModifiable
+-                , public ::com::sun::star::embed::XEncryptionProtectedSource2
++                , public ::com::sun::star::embed::XEncryptionProtectedStorage
+                 , public ::com::sun::star::beans::XPropertySet
+                 , public ::com::sun::star::embed::XOptimizedStorage
+                 , public ::com::sun::star::embed::XRelationshipAccess
+@@ -647,6 +647,11 @@ public:
+         throw ( ::com::sun::star::io::IOException,
+                 ::com::sun::star::uno::RuntimeException );
+ 
++    //____________________________________________________________________________________________________
++    //  XEncryptionProtectedStorage
++    //____________________________________________________________________________________________________
++
++    virtual void SAL_CALL setEncryptionAlgorithms( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aAlgorithms ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ 
+     //____________________________________________________________________________________________________
+     //	XPropertySet
+diff --git a/package/source/zipapi/EntryInputStream.cxx b/package/source/zipapi/EntryInputStream.cxx
+deleted file mode 100644
+index 00ae61f..0000000
+--- a/package/source/zipapi/EntryInputStream.cxx
++++ /dev/null
+@@ -1,205 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-
+-// MARKER(update_precomp.py): autogen include statement, do not remove
+-#include "precompiled_package.hxx"
+-#include <EntryInputStream.hxx>
+-#include <com/sun/star/packages/zip/ZipConstants.hpp>
+-#include <rtl/cipher.h>
+-#include <rtl/digest.h>
+-#include <memory.h> // for memcpy
+-
+-using namespace com::sun::star;
+-using namespace com::sun::star::uno;
+-using namespace com::sun::star::packages::zip;
+-using namespace com::sun::star::packages::zip::ZipConstants;
+-
+-using ::rtl::OUString;
+-
+-/** Provides access to the compressed data in a zipfile. 
+- *
+- * uncompresses the stream into memory and seeks on it 'in memory'
+- * This and the ZipPackageBuffer used in the ZipOutputStream are memory hogs
+- * and will hopefully be replaced eventually
+- *
+- * Acts on the same underlying XInputStream as both the full Zip File and other
+- * EntryInputStreams, and thus must maintain its current position in the stream and
+- * seek to it before performing any reads.
+- */
+-
+-EntryInputStream::EntryInputStream( Reference < io::XInputStream > xNewInput, 
+-                                    const ZipEntry & rNewEntry,
+-                                    const rtl::Reference < EncryptionData > &xEncryptData,
+-                                    sal_Bool bGetRawStream)
+-: xStream( xNewInput )
+-, xSeek( xNewInput, UNO_QUERY )
+-, aEntry (rNewEntry )
+-, nCurrent( 0 )
+-, bHaveInMemory ( sal_False )
+-, aInflater( sal_True )
+-, aBuffer( 0 )
+-, xEncryptionData (xEncryptData)
+-, bRawStream (bGetRawStream)
+-{
+-    if (bGetRawStream)
+-    {
+-        nUncompressedSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+-        nEnd = aEntry.nOffset + nUncompressedSize;
+-    }
+-    else
+-    {
+-        nEnd = aEntry.nMethod == DEFLATED ? aEntry.nOffset + aEntry.nCompressedSize : aEntry.nOffset + aEntry.nSize;
+-        nUncompressedSize = aEntry.nSize;
+-    }
+-}
+-void EntryInputStream::readIntoMemory()
+-    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+-{
+-    if (!bHaveInMemory)
+-    {
+-        Sequence < sal_Int8 > aReadBuffer;
+-        xSeek->seek(aEntry.nOffset);
+-        sal_Int32 nSize = aEntry.nMethod == DEFLATED ? aEntry.nCompressedSize : aEntry.nSize;
+-
+-        if (nSize <0)
+-            throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+-
+-        xStream->readBytes( aReadBuffer, nSize ); // Now it holds the raw stuff from disk
+-
+-        if (xEncryptionData->aSalt.getLength())
+-        {
+-            // Have salt, will travel
+-            Sequence < sal_uInt8 > aDerivedKey (16);
+-            rtlCipherError aResult;
+-            Sequence < sal_Int8 > aDecryptBuffer;
+-
+-            // Get the key
+-            rtl_digest_PBKDF2 ( aDerivedKey.getArray(), 16,
+-                                reinterpret_cast < const sal_uInt8 * > (xEncryptionData->aKey.getConstArray()), 
+-                                xEncryptionData->aKey.getLength(),
+-                                xEncryptionData->aSalt.getConstArray(), 
+-                                xEncryptionData->aSalt.getLength(),
+-                                xEncryptionData->nIterationCount );
+-            
+-            rtlCipher aCipher = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+-            aResult = rtl_cipher_init( aCipher, rtl_Cipher_DirectionDecode, 
+-                                       aDerivedKey.getConstArray(),
+-                                       aDerivedKey.getLength(),
+-                                       xEncryptionData->aInitVector.getConstArray(),
+-                                       xEncryptionData->aInitVector.getLength());
+-            OSL_ASSERT (aResult == rtl_Cipher_E_None);
+-            aDecryptBuffer.realloc ( nSize );
+-            aResult = rtl_cipher_decode ( aCipher, 
+-                                          aReadBuffer.getConstArray(), 
+-                                          nSize,
+-                                          reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+-                                          nSize);
+-            OSL_ASSERT (aResult == rtl_Cipher_E_None);
+-            aReadBuffer = aDecryptBuffer; // Now it holds the decrypted data
+-        }
+-        if (bRawStream || aEntry.nMethod == STORED)
+-            aBuffer = aReadBuffer; // bRawStream means the caller doesn't want it decompressed
+-        else
+-        {
+-            aInflater.setInputSegment(aReadBuffer, 0, nSize );
+-            aBuffer.realloc( aEntry.nSize );
+-            aInflater.doInflate(aBuffer);
+-            aInflater.end();
+-        }
+-        bHaveInMemory = sal_True;
+-    }
+-}
+-EntryInputStream::~EntryInputStream( void )
+-{
+-}
+-
+-sal_Int32 SAL_CALL EntryInputStream::readBytes( Sequence< sal_Int8 >& aData,
+-                                        sal_Int32 nBytesToRead )
+-    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+-{
+-    if (nBytesToRead <0)
+-        throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+-    if (!bHaveInMemory)
+-        readIntoMemory();
+-    if (nBytesToRead + nCurrent > nUncompressedSize)
+-        nBytesToRead = static_cast < sal_Int32> ( nUncompressedSize - nCurrent );
+-
+-    aData.realloc( nBytesToRead );
+-    memcpy(aData.getArray(), aBuffer.getConstArray() + nCurrent, nBytesToRead);
+-    nCurrent+=nBytesToRead;
+-
+-    return nBytesToRead;
+-}
+-sal_Int32 SAL_CALL EntryInputStream::readSomeBytes( Sequence< sal_Int8 >& aData,
+-                                                sal_Int32 nMaxBytesToRead )
+-    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+-{
+-    return readBytes( aData, nMaxBytesToRead );
+-}
+-void SAL_CALL EntryInputStream::skipBytes( sal_Int32 nBytesToSkip )
+-    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, RuntimeException)
+-{
+-    if (nBytesToSkip < 0)
+-        throw io::BufferSizeExceededException(::rtl::OUString(), *this);
+-
+-    if (nBytesToSkip + nCurrent > nUncompressedSize)
+-        nBytesToSkip = static_cast < sal_Int32 > (nUncompressedSize- nCurrent);
+-
+-    nCurrent+=nBytesToSkip;
+-}
+-sal_Int32 SAL_CALL EntryInputStream::available(  ) 
+-    throw(io::NotConnectedException, io::IOException, RuntimeException)
+-{
+-    return static_cast < sal_Int32 > (nUncompressedSize - nCurrent);
+-}
+-void SAL_CALL EntryInputStream::closeInput(  ) 
+-    throw(io::NotConnectedException, io::IOException, RuntimeException)
+-{
+-}
+-
+-void SAL_CALL EntryInputStream::seek( sal_Int64 location ) 
+-    throw(lang::IllegalArgumentException, io::IOException, RuntimeException)
+-{
+-    if (location > nUncompressedSize)
+-        location = nUncompressedSize;
+-    if (location <0)
+-        location = 0;
+-    nCurrent = location;
+-}
+-sal_Int64 SAL_CALL EntryInputStream::getPosition(  ) 
+-        throw(io::IOException, RuntimeException)
+-{
+-    return nCurrent;
+-}
+-sal_Int64 SAL_CALL EntryInputStream::getLength(  )
+-        throw(io::IOException, RuntimeException)
+-{
+-    return nUncompressedSize;
+-}
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/EntryInputStream.hxx b/package/source/zipapi/EntryInputStream.hxx
+deleted file mode 100644
+index cf1bf5a..0000000
+--- a/package/source/zipapi/EntryInputStream.hxx
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-#ifndef _ENTRY_INPUT_STREAM_HXX
+-#define _ENTRY_INPUT_STREAM_HXX
+-
+-#include <cppuhelper/implbase2.hxx> // helper for implementations
+-#include <com/sun/star/io/XInputStream.hpp>
+-#include <com/sun/star/io/XSeekable.hpp>
+-#include <Inflater.hxx>
+-#include <com/sun/star/packages/zip/ZipEntry.hpp>
+-#include <rtl/ref.hxx>
+-#include <EncryptionData.hxx>
+-class EntryInputStream : public cppu::WeakImplHelper2< com::sun::star::io::XInputStream, 
+-                                                       com::sun::star::io::XSeekable >
+-{
+-protected:
+-    com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xStream;
+-    com::sun::star::uno::Reference< com::sun::star::io::XSeekable > xSeek;
+-    sal_Int64 nEnd, nCurrent, nUncompressedSize;
+-    sal_Bool bRawStream, bHaveInMemory, bEncrypted;
+-    com::sun::star::uno::Sequence < sal_Int8 > aBuffer;
+-    const rtl::Reference < EncryptionData > xEncryptionData;
+-    const com::sun::star::packages::zip::ZipEntry aEntry;
+-    Inflater aInflater;
+-    void readIntoMemory()
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-public:
+-             EntryInputStream( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xInput, 
+-                                const com::sun::star::packages::zip::ZipEntry &rNewEntry, 
+-                               const rtl::Reference < EncryptionData > &xEncryptData,
+-                               sal_Bool bGetRawStream = sal_False);
+-    virtual ~EntryInputStream();
+-
+-    // XInputStream
+-    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) 
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) 
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) 
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int32 SAL_CALL available(  ) 
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL closeInput(  ) 
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    // XSeekable
+-    virtual void SAL_CALL seek( sal_Int64 location ) 
+-        throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int64 SAL_CALL getPosition(  ) 
+-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int64 SAL_CALL getLength(  ) 
+-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    /*
+-private:
+-    void fill( void );
+-    */
+-};
+-
+-#endif
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/XFileStream.cxx b/package/source/zipapi/XFileStream.cxx
+deleted file mode 100644
+index 6afe807..0000000
+--- a/package/source/zipapi/XFileStream.cxx
++++ /dev/null
+@@ -1,230 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-
+-// MARKER(update_precomp.py): autogen include statement, do not remove
+-#include "precompiled_package.hxx"
+-#include <XFileStream.hxx>
+-#include <EncryptionData.hxx>
+-#include <com/sun/star/packages/zip/ZipConstants.hpp>
+-#include <PackageConstants.hxx>
+-#include <rtl/cipher.h>
+-#include <ZipFile.hxx>
+-#include <EncryptedDataHeader.hxx>
+-#include <com/sun/star/io/XOutputStream.hpp>
+-
+-using namespace com::sun::star::packages::zip::ZipConstants;
+-using namespace com::sun::star::io;
+-using namespace com::sun::star::uno;
+-using com::sun::star::lang::IllegalArgumentException;
+-using ::rtl::OUString;
+-
+-XFileStream::XFileStream( ZipEntry & rEntry,
+-                           com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+-                           com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream,
+-                           const rtl::Reference < EncryptionData > &rData,
+-                           sal_Bool bNewRawStream,
+-                           sal_Bool bIsEncrypted )
+-: maEntry ( rEntry )
+-, mxData ( rData )
+-, mbRawStream ( bNewRawStream )
+-, mbFinished ( sal_False )
+-, mxTempIn ( xNewTempStream )
+-, mxTempSeek ( xNewTempStream, UNO_QUERY )
+-, mxTempOut ( xNewTempStream, UNO_QUERY )
+-, mxZipStream ( xNewZipStream )
+-, mxZipSeek ( xNewZipStream, UNO_QUERY )
+-, maInflater ( sal_True )
+-, maCipher ( NULL )
+-{
+-    mnZipCurrent = maEntry.nOffset;
+-    if (mbRawStream)
+-    {
+-        mnZipSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize;
+-        mnZipEnd = maEntry.nOffset + mnZipSize;
+-    }
+-    else
+-    {
+-        mnZipSize = maEntry.nSize;
+-        mnZipEnd = maEntry.nMethod == DEFLATED ? maEntry.nOffset + maEntry.nCompressedSize : maEntry.nOffset + maEntry.nSize;
+-    }
+-
+-    if ( bIsEncrypted )
+-    {
+-        sal_Bool bHaveEncryptData = ( !rData.isEmpty() && rData->aSalt.getLength() && rData->aInitVector.getLength() && rData->nIterationCount != 0 ) ? sal_True : sal_False;
+-
+-        // if we have all the encrypted data, and want a raw stream, then prepend it to the stream, otherwise
+-        // make a cipher so we can decrypt it
+-        if ( bHaveEncryptData )
+-        {
+-            if ( !bNewRawStream )
+-                ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
+-            else
+-            {
+-                // Put in the EncryptedDataHeader
+-                Sequence < sal_Int8 > aEncryptedDataHeader ( n_ConstHeaderSize +
+-                                                             rData->aInitVector.getLength() +
+-                                                             rData->aSalt.getLength() +
+-                                                             rData->aDigest.getLength() );
+-                sal_Int8 * pHeader = aEncryptedDataHeader.getArray();
+-                ZipFile::StaticFillHeader ( rData, rEntry.nSize, pHeader );
+-                mxTempOut->writeBytes ( aEncryptedDataHeader );
+-                mnZipSize += mxTempSeek->getPosition();
+-                mxTempSeek->seek ( 0 );
+-            }
+-        }
+-    }
+-}
+-
+-XFileStream::~XFileStream()
+-{
+-    if ( maCipher )
+-        rtl_cipher_destroy ( maCipher );
+-}
+-
+-void XFileStream::fill( sal_Int64 nUntil)
+-{
+-    sal_Int32 nRead;
+-    sal_Int64 nPosition = mxTempSeek->getPosition();
+-    mxTempSeek->seek ( mxTempSeek->getLength() );
+-    maBuffer.realloc ( n_ConstBufferSize );
+-
+-    while ( mxTempSeek->getLength() < nUntil )
+-    {
+-        if ( !mbRawStream )
+-        {
+-            while ( 0 == ( nRead = maInflater.doInflate( maBuffer ) ) )
+-            {
+-                if ( maInflater.finished() || maInflater.needsDictionary() )
+-                {
+-                    // some error handling ?
+-                    return;
+-                }
+-
+-                sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
+-                if ( nDiff > 0 )
+-                {
+-                    mxZipSeek->seek ( mnZipCurrent );
+-                    nRead = mxZipStream->readBytes ( maCompBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) );
+-                    mnZipCurrent += nRead;
+-                    // maCompBuffer now has the uncompressed data, check if we need to decrypt
+-                    // before passing to the Inflater
+-                    if ( maCipher )
+-                    {
+-                        Sequence < sal_Int8 > aCryptBuffer ( nRead );
+-                        rtlCipherError aResult = rtl_cipher_decode ( maCipher,
+-                                      maCompBuffer.getConstArray(),
+-                                      nRead,
+-                                      reinterpret_cast < sal_uInt8 * > (aCryptBuffer.getArray()),
+-                                      nRead);
+-                        OSL_ASSERT (aResult == rtl_Cipher_E_None);
+-                        maCompBuffer = aCryptBuffer; // Now it holds the decrypted data
+-
+-                    }
+-                    maInflater.setInput ( maCompBuffer );
+-                }
+-                else
+-                {
+-                    // some error handling ?
+-                    return;
+-                }
+-            }
+-        }
+-        else
+-        {
+-            sal_Int64 nDiff = mnZipEnd - mnZipCurrent;
+-            mxZipSeek->seek ( mnZipCurrent );
+-            nRead = mxZipStream->readBytes ( maBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) );
+-            mnZipCurrent += nRead;
+-        }
+-        Sequence < sal_Int8 > aTmpBuffer ( maBuffer.getConstArray(), nRead );
+-        mxTempOut->writeBytes ( aTmpBuffer );
+-    }
+-    mxTempSeek->seek ( nPosition );
+-}
+-
+-sal_Int32 SAL_CALL XFileStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+-        throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+-{
+-    sal_Int64 nPosition = mxTempSeek->getPosition();
+-    if ( nPosition + nBytesToRead > mnZipSize )
+-        nBytesToRead = static_cast < sal_Int32 > ( mnZipSize - nPosition );
+-
+-    sal_Int64 nUntil = nBytesToRead + nPosition + n_ConstBufferSize;
+-    if (nUntil > mnZipSize )
+-        nUntil = mnZipSize;
+-    if ( nUntil > mxTempSeek->getLength() )
+-        fill ( nUntil );
+-    sal_Int32 nRead = mxTempIn->readBytes ( aData, nBytesToRead );
+-    return nRead;
+-}
+-
+-sal_Int32 SAL_CALL XFileStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+-        throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+-{
+-    return readBytes ( aData, nMaxBytesToRead );
+-}
+-void SAL_CALL XFileStream::skipBytes( sal_Int32 nBytesToSkip )
+-        throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
+-{
+-    seek ( mxTempSeek->getPosition() + nBytesToSkip );
+-}
+-
+-sal_Int32 SAL_CALL XFileStream::available(  )
+-        throw( NotConnectedException, IOException, RuntimeException)
+-{
+-    return static_cast < sal_Int32 > ( mnZipSize - mxTempSeek->getPosition() );
+-}
+-
+-void SAL_CALL XFileStream::closeInput(  )
+-        throw( NotConnectedException, IOException, RuntimeException)
+-{
+-}
+-void SAL_CALL XFileStream::seek( sal_Int64 location )
+-        throw( IllegalArgumentException, IOException, RuntimeException)
+-{
+-    if ( location > mnZipSize || location < 0 )
+-        throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
+-    if ( location > mxTempSeek->getLength() )
+-    {
+-        sal_Int64 nUntil = location + n_ConstBufferSize > mnZipSize ? mnZipSize : location + n_ConstBufferSize;
+-        fill ( nUntil );
+-    }
+-    mxTempSeek->seek ( location );
+-}
+-sal_Int64 SAL_CALL XFileStream::getPosition(  )
+-        throw(IOException, RuntimeException)
+-{
+-    return mxTempSeek->getPosition();
+-}
+-sal_Int64 SAL_CALL XFileStream::getLength(  )
+-        throw(IOException, RuntimeException)
+-{
+-    return mnZipSize;
+-}
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/XFileStream.hxx b/package/source/zipapi/XFileStream.hxx
+deleted file mode 100644
+index 51518de..0000000
+--- a/package/source/zipapi/XFileStream.hxx
++++ /dev/null
+@@ -1,95 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-#ifndef _XFILE_STREAM_HXX
+-#define _XFILE_STREAM_HXX
+-
+-#include <com/sun/star/lang/IllegalArgumentException.hpp>
+-#include <com/sun/star/io/XSeekable.hpp>
+-#include <com/sun/star/io/XInputStream.hpp>
+-#include <cppuhelper/implbase2.hxx>
+-#include <rtl/ref.hxx>
+-#include <Inflater.hxx>
+-#include <ZipEntry.hxx>
+-
+-namespace com { namespace sun { namespace star {
+-    namespace io { class XOutputStream; }
+-} } }
+-class EncryptionData;
+-typedef void* rtlCipher;
+-class XFileStream : public cppu::WeakImplHelper2
+-<
+-    com::sun::star::io::XInputStream,
+-    com::sun::star::io::XSeekable
+->
+-{
+-protected:
+-    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxZipStream;
+-    com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxZipSeek;
+-    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxTempIn;
+-    com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxTempSeek;
+-    com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > mxTempOut;
+-    com::sun::star::uno::Sequence < sal_Int8 > maBuffer, maCompBuffer;
+-    ZipEntry maEntry;
+-    rtl::Reference < EncryptionData > mxData;
+-    rtlCipher maCipher;
+-    Inflater maInflater;
+-    sal_Bool mbRawStream, mbFinished;
+-    sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize;
+-    void fill( sal_Int64 nUntil );
+-
+-public:
+-    XFileStream( ZipEntry & rEntry,
+-                 com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+-                 com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream,
+-                 const rtl::Reference < EncryptionData > &rData,
+-                 sal_Bool bRawStream,
+-                 sal_Bool bIsEncrypted );
+-    virtual ~XFileStream();
+-
+-    // XInputStream
+-    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int32 SAL_CALL available(  )
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL closeInput(  )
+-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    // XSeekable
+-    virtual void SAL_CALL seek( sal_Int64 location )
+-        throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int64 SAL_CALL getPosition(  )
+-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-    virtual sal_Int64 SAL_CALL getLength(  )
+-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+-};
+-#endif
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/XMemoryStream.cxx b/package/source/zipapi/XMemoryStream.cxx
+deleted file mode 100644
+index 8b737db..0000000
+--- a/package/source/zipapi/XMemoryStream.cxx
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-
+-// MARKER(update_precomp.py): autogen include statement, do not remove
+-#include "precompiled_package.hxx"
+-#include <XMemoryStream.hxx>
+-
+-using namespace com::sun::star::io;
+-using namespace com::sun::star::uno;
+-
+-XMemoryStream::XMemoryStream ( com::sun::star::uno::Sequence < sal_Int8 > & rNewBuffer )
+-: ZipPackageBuffer ( rNewBuffer )
+-{
+-}
+-XMemoryStream::~XMemoryStream(void)
+-{
+-}
+-::com::sun::star::uno::Any SAL_CALL XMemoryStream::queryInterface( const com::sun::star::uno::Type& rType ) 
+-        throw(com::sun::star::uno::RuntimeException)
+-{
+-    return ::cppu::queryInterface ( rType										,
+-                                    // OWeakObject interfaces
+-                                    reinterpret_cast< XInterface*		> ( this )	,
+-                                    static_cast< XWeak*			> ( this )	,
+-                                    // my interfaces
+-                                    static_cast< XInputStream*		> ( this )	,
+-                                    static_cast< XSeekable*		> ( this ) );
+-}
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/XMemoryStream.hxx b/package/source/zipapi/XMemoryStream.hxx
+deleted file mode 100644
+index e6bc88e..0000000
+--- a/package/source/zipapi/XMemoryStream.hxx
++++ /dev/null
+@@ -1,45 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-#ifndef _XMEMORY_STREAM_HXX
+-#define _XMEMORY_STREAM_HXX
+-
+-#include <ZipPackageBuffer.hxx>
+-
+-class ZipPackage;
+-
+-class XMemoryStream: public ZipPackageBuffer
+-{
+-public:
+-    XMemoryStream ( com::sun::star::uno::Sequence < sal_Int8 > & rNewBuffer );
+-    virtual ~XMemoryStream(void);
+-    virtual com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type& rType ) 
+-        throw(com::sun::star::uno::RuntimeException);
+-};
+-#endif
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx
+index 1cad883..bb757e6 100644
+--- a/package/source/zipapi/XUnbufferedStream.cxx
++++ b/package/source/zipapi/XUnbufferedStream.cxx
+@@ -32,8 +32,9 @@
+ #include <EncryptionData.hxx>
+ #include <com/sun/star/packages/zip/ZipConstants.hpp>
+ #include <com/sun/star/packages/zip/ZipIOException.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
++
+ #include <PackageConstants.hxx>
+-#include <rtl/cipher.h>
+ #include <ZipFile.hxx>
+ #include <EncryptedDataHeader.hxx>
+ #include <algorithm>
+@@ -48,6 +49,7 @@
+ using namespace ::com::sun::star;
+ #endif
+ 
++using namespace ::com::sun::star;
+ using namespace com::sun::star::packages::zip::ZipConstants;
+ using namespace com::sun::star::io;
+ using namespace com::sun::star::uno;
+@@ -55,7 +57,9 @@ using com::sun::star::lang::IllegalArgumentException;
+ using com::sun::star::packages::zip::ZipIOException;
+ using ::rtl::OUString;
+ 
+-XUnbufferedStream::XUnbufferedStream( SotMutexHolderRef aMutexHolder,
++XUnbufferedStream::XUnbufferedStream(
++                      const uno::Reference< lang::XMultiServiceFactory >& xFactory,
++                      SotMutexHolderRef aMutexHolder,
+                           ZipEntry & rEntry,
+                            Reference < XInputStream > xNewZipStream,
+                           const rtl::Reference < EncryptionData > &rData,
+@@ -68,7 +72,7 @@ XUnbufferedStream::XUnbufferedStream( SotMutexHolderRef aMutexHolder,
+ , mxZipSeek ( xNewZipStream, UNO_QUERY )
+ , maEntry ( rEntry )
+ , mxData ( rData )
+-, maCipher ( NULL )
++, mnBlockSize( 1 )
+ , maInflater ( sal_True )
+ , mbRawStream ( nStreamMode == UNBUFF_STREAM_RAW || nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
+ , mbWrappedRaw ( nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
+@@ -91,11 +95,15 @@ XUnbufferedStream::XUnbufferedStream( SotMutexHolderRef aMutexHolder,
+         mnZipSize = maEntry.nSize;
+         mnZipEnd = maEntry.nMethod == DEFLATED ? maEntry.nOffset + maEntry.nCompressedSize : maEntry.nOffset + maEntry.nSize;
+     }
+-    sal_Bool bHaveEncryptData = ( rData.is() && rData->aSalt.getLength() && rData->aInitVector.getLength() && rData->nIterationCount != 0 ) ? sal_True : sal_False;
++    sal_Bool bHaveEncryptData = ( rData.is() && rData->m_aSalt.getLength() && rData->m_aInitVector.getLength() && rData->m_nIterationCount != 0 ) ? sal_True : sal_False;
+     sal_Bool bMustDecrypt = ( nStreamMode == UNBUFF_STREAM_DATA && bHaveEncryptData && bIsEncrypted ) ? sal_True : sal_False;
+ 
+     if ( bMustDecrypt )
+-        ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
++    {
++        m_xCipherContext = ZipFile::StaticGetCipher( xFactory, rData, false );
++        mnBlockSize = ( rData->m_nEncAlg == xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 1 );
++    }
++
+     if ( bHaveEncryptData && mbWrappedRaw && bIsEncrypted )
+     {
+         // if we have the data needed to decrypt it, but didn't want it decrypted (or
+@@ -104,24 +112,26 @@ XUnbufferedStream::XUnbufferedStream( SotMutexHolderRef aMutexHolder,
+ 
+         // Make a buffer big enough to hold both the header and the data itself
+         maHeader.realloc  ( n_ConstHeaderSize +
+-                            rData->aInitVector.getLength() +
+-                            rData->aSalt.getLength() +
+-                            rData->aDigest.getLength() +
++                            rData->m_aInitVector.getLength() +
++                            rData->m_aSalt.getLength() +
++                            rData->m_aDigest.getLength() +
+                             aMediaType.getLength() * sizeof( sal_Unicode ) );
+         sal_Int8 * pHeader = maHeader.getArray();
+-        ZipFile::StaticFillHeader ( rData, rEntry.nSize, aMediaType, pHeader );
++        ZipFile::StaticFillHeader( rData, rEntry.nSize, aMediaType, pHeader );
+         mnHeaderToRead = static_cast < sal_Int16 > ( maHeader.getLength() );
+     }
+ }
+ 
+ // allows to read package raw stream
+-XUnbufferedStream::XUnbufferedStream( const Reference < XInputStream >& xRawStream,
+-                    const rtl::Reference < EncryptionData > &rData )
++XUnbufferedStream::XUnbufferedStream(
++                    const uno::Reference< lang::XMultiServiceFactory >& /*xFactory*/,
++                    const Reference < XInputStream >& xRawStream,
++                    const ::rtl::Reference< EncryptionData >& rData )
+ : maMutexHolder( new SotMutexHolder )
+ , mxZipStream ( xRawStream )
+ , mxZipSeek ( xRawStream, UNO_QUERY )
+ , mxData ( rData )
+-, maCipher ( NULL )
++, mnBlockSize( 1 )
+ , maInflater ( sal_True )
+ , mbRawStream ( sal_False )
+ , mbWrappedRaw ( sal_False )
+@@ -137,8 +147,8 @@ XUnbufferedStream::XUnbufferedStream( const Reference < XInputStream >& xRawStre
+     OSL_ENSURE( mxZipSeek.is(), "The stream must be seekable!\n" );
+ 
+     // skip raw header, it must be already parsed to rData
+-    mnZipCurrent = n_ConstHeaderSize + rData->aInitVector.getLength() +
+-                            rData->aSalt.getLength() + rData->aDigest.getLength();
++    mnZipCurrent = n_ConstHeaderSize + rData->m_aInitVector.getLength() +
++                            rData->m_aSalt.getLength() + rData->m_aDigest.getLength();
+ 
+     try {
+         if ( mxZipSeek.is() )
+@@ -150,13 +160,12 @@ XUnbufferedStream::XUnbufferedStream( const Reference < XInputStream >& xRawStre
+ 
+     mnZipEnd = mnZipCurrent + mnZipSize;
+ 
+-    ZipFile::StaticGetCipher ( rData, maCipher, sal_True );
++    // the raw data will not be decrypted, no need for the cipher
++    // m_xCipherContext = ZipFile::StaticGetCipher( xFactory, rData, false );
+ }
+ 
+ XUnbufferedStream::~XUnbufferedStream()
+ {
+-    if ( maCipher )
+-        rtl_cipher_destroy ( maCipher );
+ }
+ 
+ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+@@ -249,7 +258,12 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
+                 if ( nDiff > 0 )
+                 {
+                     mxZipSeek->seek ( mnZipCurrent );
+-                    sal_Int32 nToRead = std::min ( nDiff, std::max ( nRequestedBytes, static_cast< sal_Int32 >( 8192 ) ) );
++
++                    sal_Int32 nToRead = std::max( nRequestedBytes, static_cast< sal_Int32 >( 8192 ) );
++                    if ( mnBlockSize > 1 )
++                        nToRead = nToRead + mnBlockSize - nToRead % mnBlockSize;
++                    nToRead = std::min( nDiff, nToRead );
++
+                     sal_Int32 nZipRead = mxZipStream->readBytes ( maCompBuffer, nToRead );
+                     if ( nZipRead < nToRead )
+                         throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No expected data!" ) ),
+@@ -258,23 +272,22 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
+                     mnZipCurrent += nZipRead;
+                     // maCompBuffer now has the data, check if we need to decrypt
+                     // before passing to the Inflater
+-                    if ( maCipher )
++                    if ( m_xCipherContext.is() )
+                     {
+                         if ( mbCheckCRC )
+                             maCRC.update( maCompBuffer );
+ 
+-                        Sequence < sal_Int8 > aCryptBuffer ( nZipRead );
+-                         rtlCipherError aResult =
+-                            rtl_cipher_decode ( maCipher,
+-                                      maCompBuffer.getConstArray(),
+-                                      nZipRead,
+-                                      reinterpret_cast < sal_uInt8 * > (aCryptBuffer.getArray()),
+-                                      nZipRead);
+-                        if( aResult != rtl_Cipher_E_None ) {
+-                            OSL_ASSERT (aResult == rtl_Cipher_E_None);
++                        maCompBuffer = m_xCipherContext->convertWithCipherContext( maCompBuffer );
++                        if ( mnZipCurrent == mnZipEnd )
++                        {
++                            Sequence< sal_Int8 > aSuffix = m_xCipherContext->finalizeCipherContextAndDispose();
++                            if ( aSuffix.getLength() )
++                            {
++                                sal_Int32 nOldLen = maCompBuffer.getLength();
++                                maCompBuffer.realloc( nOldLen + aSuffix.getLength() );
++                                rtl_copyMemory( maCompBuffer.getArray() + nOldLen, aSuffix.getConstArray(), aSuffix.getLength() );
++                        }
+                         }
+-                        maCompBuffer = aCryptBuffer; // Now it holds the decrypted data
+-
+                     }
+                     maInflater.setInput ( maCompBuffer );
+                 }
+@@ -293,7 +306,7 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
+ 
+         if ( mbCheckCRC && ( !mbRawStream || mbWrappedRaw ) )
+         {
+-            if ( !maCipher && !mbWrappedRaw )
++            if ( !m_xCipherContext.is() && !mbWrappedRaw )
+                 maCRC.update( aData );
+ 
+ #if 0
+diff --git a/package/source/zipapi/XUnbufferedStream.hxx b/package/source/zipapi/XUnbufferedStream.hxx
+index 5cf7272..aa58ca7 100644
+--- a/package/source/zipapi/XUnbufferedStream.hxx
++++ b/package/source/zipapi/XUnbufferedStream.hxx
+@@ -32,6 +32,8 @@
+ #include <com/sun/star/io/XSeekable.hpp>
+ #include <com/sun/star/io/XInputStream.hpp>
+ #include <com/sun/star/io/XOutputStream.hpp>
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++
+ #include <cppuhelper/implbase1.hxx>
+ #include <rtl/ref.hxx>
+ #include <Inflater.hxx>
+@@ -44,7 +46,6 @@
+ #define UNBUFF_STREAM_WRAPPEDRAW	2
+ 
+ class EncryptionData;
+-typedef void* rtlCipher;
+ class XUnbufferedStream : public cppu::WeakImplHelper1
+ <
+     com::sun::star::io::XInputStream
+@@ -58,7 +59,8 @@ protected:
+     com::sun::star::uno::Sequence < sal_Int8 > maCompBuffer, maHeader;
+     ZipEntry maEntry;
+     rtl::Reference < EncryptionData > mxData;
+-    rtlCipher maCipher;
++    sal_Int32 mnBlockSize;
++    ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext;
+     ZipUtils::Inflater maInflater;
+     sal_Bool mbRawStream, mbWrappedRaw, mbFinished;
+     sal_Int16 mnHeaderToRead;
+@@ -68,6 +70,7 @@ protected:
+ 
+ public:
+     XUnbufferedStream(
++                 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
+                  SotMutexHolderRef aMutexHolder,
+                  ZipEntry & rEntry,
+                  com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream,
+@@ -78,8 +81,10 @@ public:
+                  sal_Bool bRecoveryMode );
+ 
+     // allows to read package raw stream
+-    XUnbufferedStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& xRawStream,
+-                 const rtl::Reference < EncryptionData > &rData );
++    XUnbufferedStream(
++                 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
++                 const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& xRawStream,
++                 const ::rtl::Reference< EncryptionData >& rData );
+ 
+ 
+     virtual ~XUnbufferedStream();
+diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
+index 2e9576b..fb56c28 100644
+--- a/package/source/zipapi/ZipFile.cxx
++++ b/package/source/zipapi/ZipFile.cxx
+@@ -32,11 +32,22 @@
+ #include <ZipEnumeration.hxx>
+ #include <com/sun/star/packages/zip/ZipConstants.hpp>
+ #include <rtl/cipher.h>
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++#include <com/sun/star/xml/crypto/XCipherContextSupplier.hpp>
++#include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
++
++#include <comphelper/processfactory.hxx>
+ #include <rtl/digest.h>
+ /*
+ #include <XMemoryStream.hxx>
+ #include <XFileStream.hxx>
+ */
++
++#include "blowfishcontext.hxx"
++#include "sha1context.hxx"
+ #include <XUnbufferedStream.hxx>
+ #include <PackageConstants.hxx>
+ #include <EncryptedDataHeader.hxx>
+@@ -47,10 +58,10 @@
+ 
+ #include <CRC32.hxx>
+ 
+-#include <string.h> // for memcpy
+ #include <vector>
+ 
+ #include <comphelper/storagehelper.hxx>
++#define AES_CBC_BLOCK_SIZE 16
+ 
+ using namespace com::sun::star;
+ using namespace com::sun::star::io;
+@@ -72,7 +83,7 @@ ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiSe
+ , aInflater (sal_True)
+ , xStream(xInput)
+ , xSeek(xInput, UNO_QUERY)
+-, xFactory ( xNewFactory )
++, m_xFactory ( xNewFactory )
+ , bRecoveryMode( sal_False )
+ {
+     if (bInitialise)
+@@ -93,7 +104,7 @@ ZipFile::ZipFile( Reference < XInputStream > &xInput, const Reference < XMultiSe
+ , aInflater (sal_True)
+ , xStream(xInput)
+ , xSeek(xInput, UNO_QUERY)
+-, xFactory ( xNewFactory )
++, m_xFactory ( xNewFactory )
+ , xProgressHandler( xProgress )
+ , bRecoveryMode( bForceRecovery )
+ {
+@@ -136,18 +147,18 @@ sal_Bool ZipFile::StaticGetCipher ( const rtl::Reference < EncryptionData > & xE
+ 
+         // Get the key
+         rtl_digest_PBKDF2 ( aDerivedKey.getArray(), 16,
+-                            reinterpret_cast < const sal_uInt8 * > (xEncryptionData->aKey.getConstArray() ),
+-                            xEncryptionData->aKey.getLength(),
+-                            reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->aSalt.getConstArray() ),
+-                            xEncryptionData->aSalt.getLength(),
+-                            xEncryptionData->nIterationCount );
++                            reinterpret_cast < const sal_uInt8 * > (xEncryptionData->m_aKey.getConstArray() ),
++                            xEncryptionData->m_aKey.getLength(),
++                            reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->m_aSalt.getConstArray() ),
++                            xEncryptionData->m_aSalt.getLength(),
++                            xEncryptionData->m_nIterationCount );
+ 
+         rCipher = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+         aResult = rtl_cipher_init( rCipher, bDecode ? rtl_Cipher_DirectionDecode : rtl_Cipher_DirectionEncode,
+                                    aDerivedKey.getConstArray(),
+                                    aDerivedKey.getLength(),
+-                                   reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->aInitVector.getConstArray() ),
+-                                   xEncryptionData->aInitVector.getLength());
++                                   reinterpret_cast < const sal_uInt8 * > ( xEncryptionData->m_aInitVector.getConstArray() ),
++                                   xEncryptionData->m_aInitVector.getLength());
+         OSL_ASSERT (aResult == rtl_Cipher_E_None);
+ 
+         bResult = ( aResult == rtl_Cipher_E_None );
+@@ -156,15 +167,85 @@ sal_Bool ZipFile::StaticGetCipher ( const rtl::Reference < EncryptionData > & xE
+     return bResult;
+ }
+ 
++uno::Reference< xml::crypto::XDigestContext > ZipFile::StaticGetDigestContextForChecksum( const uno::Reference< lang::XMultiServiceFactory >& xArgFactory, const ::rtl::Reference< EncryptionData >& xEncryptionData )
++{
++    uno::Reference< xml::crypto::XDigestContext > xDigestContext;
++    if ( xEncryptionData->m_nCheckAlg == xml::crypto::DigestID::SHA256_1K )
++    {
++        uno::Reference< lang::XMultiServiceFactory > xFactory = xArgFactory;
++        if ( !xFactory.is() )
++            xFactory.set( comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
++
++        uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier(
++            xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ),
++            uno::UNO_QUERY_THROW );
++
++        xDigestContext.set( xDigestContextSupplier->getDigestContext( xEncryptionData->m_nCheckAlg, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
++    }
++    else if ( xEncryptionData->m_nCheckAlg == xml::crypto::DigestID::SHA1_1K )
++        xDigestContext.set( SHA1DigestContext::Create(), uno::UNO_SET_THROW );
++
++    return xDigestContext;
++}
++
++uno::Reference< xml::crypto::XCipherContext > ZipFile::StaticGetCipher( const uno::Reference< lang::XMultiServiceFactory >& xArgFactory, const ::rtl::Reference< EncryptionData >& xEncryptionData, bool bEncrypt )
++{
++    uno::Reference< xml::crypto::XCipherContext > xResult;
++
++    try
++    {
++        uno::Sequence< sal_Int8 > aDerivedKey( xEncryptionData->m_nDerivedKeySize );
++        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(),
++                                   reinterpret_cast< const sal_uInt8 * > ( xEncryptionData->m_aSalt.getConstArray() ),
++                                   xEncryptionData->m_aSalt.getLength(),
++                                   xEncryptionData->m_nIterationCount ) )
++        {
++            throw ZipIOException( ::rtl::OUString::createFromAscii( "Can not create derived key!\n" ),
++                                  uno::Reference< XInterface >() );
++    }
++
++        if ( xEncryptionData->m_nEncAlg == xml::crypto::CipherID::AES_CBC_W3C_PADDING )
++        {
++            uno::Reference< lang::XMultiServiceFactory > xFactory = xArgFactory;
++            if ( !xFactory.is() )
++                xFactory.set( comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
++
++            uno::Reference< xml::crypto::XCipherContextSupplier > xCipherContextSupplier(
++                xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ),
++                uno::UNO_QUERY_THROW );
++
++            xResult = xCipherContextSupplier->getCipherContext( xEncryptionData->m_nEncAlg, aDerivedKey, xEncryptionData->m_aInitVector, bEncrypt, uno::Sequence< beans::NamedValue >() );
++        }
++        else if ( xEncryptionData->m_nEncAlg == xml::crypto::CipherID::BLOWFISH_CFB_8 )
++        {
++            xResult = BlowfishCFB8CipherContext::Create( aDerivedKey, xEncryptionData->m_aInitVector, bEncrypt );
++        }
++        else
++        {
++            throw ZipIOException( ::rtl::OUString::createFromAscii( "Unknown cipher algorithm is requested!\n" ),
++                                  uno::Reference< XInterface >() );
++        }
++    }
++    catch( uno::Exception& )
++    {
++        OSL_ENSURE( sal_False, "Can not create cipher context!" );
++    }
++
++    return xResult;
++}
++
+ void ZipFile::StaticFillHeader ( const rtl::Reference < EncryptionData > & rData,
+                                 sal_Int32 nSize,
+                                 const ::rtl::OUString& aMediaType,
+                                 sal_Int8 * & pHeader )
+ {
+     // I think it's safe to restrict vector and salt length to 2 bytes !
+-    sal_Int16 nIVLength = static_cast < sal_Int16 > ( rData->aInitVector.getLength() );
+-    sal_Int16 nSaltLength = static_cast < sal_Int16 > ( rData->aSalt.getLength() );
+-    sal_Int16 nDigestLength = static_cast < sal_Int16 > ( rData->aDigest.getLength() );
++    sal_Int16 nIVLength = static_cast < sal_Int16 > ( rData->m_aInitVector.getLength() );
++    sal_Int16 nSaltLength = static_cast < sal_Int16 > ( rData->m_aSalt.getLength() );
++    sal_Int16 nDigestLength = static_cast < sal_Int16 > ( rData->m_aDigest.getLength() );
+     sal_Int16 nMediaTypeLength = static_cast < sal_Int16 > ( aMediaType.getLength() * sizeof( sal_Unicode ) );
+ 
+     // First the header
+@@ -178,7 +259,7 @@ void ZipFile::StaticFillHeader ( const rtl::Reference < EncryptionData > & rData
+     *(pHeader++) = ( n_ConstCurrentVersion >> 8 ) & 0xFF;
+ 
+     // Then the iteration Count
+-    sal_Int32 nIterationCount = rData->nIterationCount;
++    sal_Int32 nIterationCount = rData->m_nIterationCount;
+     *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 0 ) & 0xFF);
+     *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 8 ) & 0xFF);
+     *(pHeader++) = static_cast< sal_Int8 >(( nIterationCount >> 16 ) & 0xFF);
+@@ -190,6 +271,34 @@ void ZipFile::StaticFillHeader ( const rtl::Reference < EncryptionData > & rData
+     *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 16 ) & 0xFF);
+     *(pHeader++) = static_cast< sal_Int8 >(( nSize >> 24 ) & 0xFF);
+ 
++    // Then the encryption algorithm
++    sal_Int32 nEncAlgID = rData->m_nEncAlg;
++    *(pHeader++) = static_cast< sal_Int8 >(( nEncAlgID >> 0 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nEncAlgID >> 8 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nEncAlgID >> 16 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nEncAlgID >> 24 ) & 0xFF);
++
++    // Then the checksum algorithm
++    sal_Int32 nChecksumAlgID = rData->m_nCheckAlg;
++    *(pHeader++) = static_cast< sal_Int8 >(( nChecksumAlgID >> 0 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nChecksumAlgID >> 8 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nChecksumAlgID >> 16 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nChecksumAlgID >> 24 ) & 0xFF);
++
++    // Then the derived key size
++    sal_Int32 nDerivedKeySize = rData->m_nDerivedKeySize;
++    *(pHeader++) = static_cast< sal_Int8 >(( nDerivedKeySize >> 0 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nDerivedKeySize >> 8 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nDerivedKeySize >> 16 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nDerivedKeySize >> 24 ) & 0xFF);
++
++    // Then the start key generation algorithm
++    sal_Int32 nKeyAlgID = rData->m_nStartKeyGenID;
++    *(pHeader++) = static_cast< sal_Int8 >(( nKeyAlgID >> 0 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nKeyAlgID >> 8 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nKeyAlgID >> 16 ) & 0xFF);
++    *(pHeader++) = static_cast< sal_Int8 >(( nKeyAlgID >> 24 ) & 0xFF);
++
+     // Then the salt length
+     *(pHeader++) = static_cast< sal_Int8 >(( nSaltLength >> 0 ) & 0xFF);
+     *(pHeader++) = static_cast< sal_Int8 >(( nSaltLength >> 8 ) & 0xFF);
+@@ -207,26 +316,30 @@ void ZipFile::StaticFillHeader ( const rtl::Reference < EncryptionData > & rData
+     *(pHeader++) = static_cast< sal_Int8 >(( nMediaTypeLength >> 8 ) & 0xFF);
+ 
+     // Then the salt content
+-    memcpy ( pHeader, rData->aSalt.getConstArray(), nSaltLength );
++    rtl_copyMemory ( pHeader, rData->m_aSalt.getConstArray(), nSaltLength );
+     pHeader += nSaltLength;
+ 
+     // Then the IV content
+-    memcpy ( pHeader, rData->aInitVector.getConstArray(), nIVLength );
++    rtl_copyMemory ( pHeader, rData->m_aInitVector.getConstArray(), nIVLength );
+     pHeader += nIVLength;
+ 
+     // Then the digest content
+-    memcpy ( pHeader, rData->aDigest.getConstArray(), nDigestLength );
++    rtl_copyMemory ( pHeader, rData->m_aDigest.getConstArray(), nDigestLength );
+     pHeader += nDigestLength;
+ 
+     // Then the mediatype itself
+-    memcpy ( pHeader, aMediaType.getStr(), nMediaTypeLength );
++    rtl_copyMemory ( pHeader, aMediaType.getStr(), nMediaTypeLength );
+     pHeader += nMediaTypeLength;
+ }
+ 
+-sal_Bool ZipFile::StaticFillData ( rtl::Reference < EncryptionData > & rData,
++sal_Bool ZipFile::StaticFillData ( rtl::Reference < BaseEncryptionData > & rData,
++                                    sal_Int32 &rEncAlg,
++                                    sal_Int32 &rChecksumAlg,
++                                    sal_Int32 &rDerivedKeySize,
++                                    sal_Int32 &rStartKeyGenID,
+                                     sal_Int32 &rSize,
+                                     ::rtl::OUString& aMediaType,
+-                                    Reference < XInputStream > &rStream )
++                                    const Reference< XInputStream >& rStream )
+ {
+     sal_Bool bOk = sal_False;
+     const sal_Int32 nHeaderSize = n_ConstHeaderSize - 4;
+@@ -243,13 +356,33 @@ sal_Bool ZipFile::StaticFillData ( rtl::Reference < EncryptionData > & rData,
+             nCount |= ( pBuffer[nPos++] & 0xFF ) << 8;
+             nCount |= ( pBuffer[nPos++] & 0xFF ) << 16;
+             nCount |= ( pBuffer[nPos++] & 0xFF ) << 24;
+-            rData->nIterationCount = nCount;
++            rData->m_nIterationCount = nCount;
+ 
+             rSize  =   pBuffer[nPos++] & 0xFF;
+             rSize |= ( pBuffer[nPos++] & 0xFF ) << 8;
+             rSize |= ( pBuffer[nPos++] & 0xFF ) << 16;
+             rSize |= ( pBuffer[nPos++] & 0xFF ) << 24;
+ 
++            rEncAlg   =   pBuffer[nPos++] & 0xFF;
++            rEncAlg  |= ( pBuffer[nPos++] & 0xFF ) << 8;
++            rEncAlg  |= ( pBuffer[nPos++] & 0xFF ) << 16;
++            rEncAlg  |= ( pBuffer[nPos++] & 0xFF ) << 24;
++
++            rChecksumAlg   =   pBuffer[nPos++] & 0xFF;
++            rChecksumAlg  |= ( pBuffer[nPos++] & 0xFF ) << 8;
++            rChecksumAlg  |= ( pBuffer[nPos++] & 0xFF ) << 16;
++            rChecksumAlg  |= ( pBuffer[nPos++] & 0xFF ) << 24;
++
++            rDerivedKeySize   =   pBuffer[nPos++] & 0xFF;
++            rDerivedKeySize  |= ( pBuffer[nPos++] & 0xFF ) << 8;
++            rDerivedKeySize  |= ( pBuffer[nPos++] & 0xFF ) << 16;
++            rDerivedKeySize  |= ( pBuffer[nPos++] & 0xFF ) << 24;
++
++            rStartKeyGenID   =   pBuffer[nPos++] & 0xFF;
++            rStartKeyGenID  |= ( pBuffer[nPos++] & 0xFF ) << 8;
++            rStartKeyGenID  |= ( pBuffer[nPos++] & 0xFF ) << 16;
++            rStartKeyGenID  |= ( pBuffer[nPos++] & 0xFF ) << 24;
++
+             sal_Int16 nSaltLength =   pBuffer[nPos++] & 0xFF;
+             nSaltLength          |= ( pBuffer[nPos++] & 0xFF ) << 8;
+             sal_Int16 nIVLength   = ( pBuffer[nPos++] & 0xFF );
+@@ -262,16 +395,16 @@ sal_Bool ZipFile::StaticFillData ( rtl::Reference < EncryptionData > & rData,
+ 
+             if ( nSaltLength == rStream->readBytes ( aBuffer, nSaltLength ) )
+             {
+-                rData->aSalt.realloc ( nSaltLength );
+-                memcpy ( rData->aSalt.getArray(), aBuffer.getConstArray(), nSaltLength );
++                rData->m_aSalt.realloc ( nSaltLength );
++                rtl_copyMemory ( rData->m_aSalt.getArray(), aBuffer.getConstArray(), nSaltLength );
+                 if ( nIVLength == rStream->readBytes ( aBuffer, nIVLength ) )
+                 {
+-                    rData->aInitVector.realloc ( nIVLength );
+-                    memcpy ( rData->aInitVector.getArray(), aBuffer.getConstArray(), nIVLength );
++                    rData->m_aInitVector.realloc ( nIVLength );
++                    rtl_copyMemory ( rData->m_aInitVector.getArray(), aBuffer.getConstArray(), nIVLength );
+                     if ( nDigestLength == rStream->readBytes ( aBuffer, nDigestLength ) )
+                     {
+-                        rData->aDigest.realloc ( nDigestLength );
+-                        memcpy ( rData->aDigest.getArray(), aBuffer.getConstArray(), nDigestLength );
++                        rData->m_aDigest.realloc ( nDigestLength );
++                        rtl_copyMemory ( rData->m_aDigest.getArray(), aBuffer.getConstArray(), nDigestLength );
+ 
+                         if ( nMediaTypeLength == rStream->readBytes ( aBuffer, nMediaTypeLength ) )
+                         {
+@@ -287,7 +420,8 @@ sal_Bool ZipFile::StaticFillData ( rtl::Reference < EncryptionData > & rData,
+     return bOk;
+ }
+ 
+-Reference< XInputStream > ZipFile::StaticGetDataFromRawStream(	const Reference< XInputStream >& xStream,
++Reference< XInputStream > ZipFile::StaticGetDataFromRawStream( const Reference< lang::XMultiServiceFactory >& xFactory,
++                                                                const Reference< XInputStream >& xStream,
+                                                                 const rtl::Reference < EncryptionData > &rData )
+         throw ( packages::WrongPasswordException, ZipIOException, RuntimeException )
+ {
+@@ -295,7 +429,7 @@ Reference< XInputStream > ZipFile::StaticGetDataFromRawStream(	const Reference<
+         throw ZipIOException( OUString(RTL_CONSTASCII_USTRINGPARAM( "Encrypted stream without encryption data!\n" )),
+                             Reference< XInterface >() );
+ 
+-    if ( !rData->aKey.getLength() )
++    if ( !rData->m_aKey.getLength() )
+         throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+     Reference< XSeekable > xSeek( xStream, UNO_QUERY );
+@@ -306,66 +440,72 @@ Reference< XInputStream > ZipFile::StaticGetDataFromRawStream(	const Reference<
+ 
+     // if we have a digest, then this file is an encrypted one and we should
+     // check if we can decrypt it or not
+-    OSL_ENSURE( rData->aDigest.getLength(), "Can't detect password correctness without digest!\n" );
+-    if ( rData->aDigest.getLength() )
++    OSL_ENSURE( rData->m_aDigest.getLength(), "Can't detect password correctness without digest!\n" );
++    if ( rData->m_aDigest.getLength() )
+     {
+             sal_Int32 nSize = sal::static_int_cast< sal_Int32 >( xSeek->getLength() );
+-        nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
++        if ( nSize > n_ConstDigestLength + 32 )
++            nSize = n_ConstDigestLength + 32;
+ 
+         // skip header
+-        xSeek->seek( n_ConstHeaderSize + rData->aInitVector.getLength() +
+-                                rData->aSalt.getLength() + rData->aDigest.getLength() );
++        xSeek->seek( n_ConstHeaderSize + rData->m_aInitVector.getLength() +
++                                rData->m_aSalt.getLength() + rData->m_aDigest.getLength() );
+ 
+         // Only want to read enough to verify the digest
+         Sequence < sal_Int8 > aReadBuffer ( nSize );
+ 
+         xStream->readBytes( aReadBuffer, nSize );
+ 
+-        if ( !StaticHasValidPassword( aReadBuffer, rData ) )
++        if ( !StaticHasValidPassword( xFactory, aReadBuffer, rData ) )
+             throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+     }
+ 
+-    return new XUnbufferedStream ( xStream, rData );
++    return new XUnbufferedStream( xFactory, xStream, rData );
+ }
+ 
+-sal_Bool ZipFile::StaticHasValidPassword( const Sequence< sal_Int8 > &aReadBuffer, const rtl::Reference < EncryptionData > &rData )
++sal_Bool ZipFile::StaticHasValidPassword( const Reference< lang::XMultiServiceFactory >& xFactory, const Sequence< sal_Int8 > &aReadBuffer, const rtl::Reference< EncryptionData > &rData )
+ {
+-    if ( !rData.is() || !rData->aKey.getLength() )
++    if ( !rData.is() || !rData->m_aKey.getLength() )
+         return sal_False;
+ 
+     sal_Bool bRet = sal_False;
+-    sal_Int32 nSize = aReadBuffer.getLength();
+ 
+-    // make a temporary cipher
+-    rtlCipher aCipher;
+-    StaticGetCipher ( rData, aCipher, sal_True );
+-
+-    Sequence < sal_Int8 > aDecryptBuffer ( nSize );
+-    rtlDigest aDigest = rtl_digest_createSHA1();
+-    rtlDigestError aDigestResult;
+-    Sequence < sal_uInt8 > aDigestSeq ( RTL_DIGEST_LENGTH_SHA1 );
+-    rtlCipherError aResult = rtl_cipher_decode ( aCipher,
+-                                  aReadBuffer.getConstArray(),
+-                                  nSize,
+-                                  reinterpret_cast < sal_uInt8 * > (aDecryptBuffer.getArray()),
+-                                  nSize);
+-    if(aResult != rtl_Cipher_E_None ) {
+-        OSL_ASSERT ( aResult == rtl_Cipher_E_None);
++    uno::Reference< xml::crypto::XCipherContext > xCipher( StaticGetCipher( xFactory, rData, false ), uno::UNO_SET_THROW );
++
++    uno::Sequence< sal_Int8 > aDecryptBuffer;
++    uno::Sequence< sal_Int8 > aDecryptBuffer2;
++    try
++    {
++        aDecryptBuffer = xCipher->convertWithCipherContext( aReadBuffer );
++        aDecryptBuffer2 = xCipher->finalizeCipherContextAndDispose();
++    }
++    catch( uno::Exception& )
++    {
++        // decryption with padding will throw the exception in finalizing if the buffer represent only part of the stream
++        // it is no problem, actually this is why we read 32 additional bytes ( two of maximal possible encryption blocks )
++    }
++
++    if ( aDecryptBuffer2.getLength() )
++    {
++        sal_Int32 nOldLen = aDecryptBuffer.getLength();
++        aDecryptBuffer.realloc( nOldLen + aDecryptBuffer2.getLength() );
++        rtl_copyMemory( aDecryptBuffer.getArray() + nOldLen, aDecryptBuffer2.getArray(), aDecryptBuffer2.getLength() );
+     }
+ 
+-    aDigestResult = rtl_digest_updateSHA1 ( aDigest,
+-                                            static_cast < const void * > ( aDecryptBuffer.getConstArray() ), nSize );
+-    OSL_ASSERT ( aDigestResult == rtl_Digest_E_None );
++    if ( aDecryptBuffer.getLength() > n_ConstDigestLength )
++        aDecryptBuffer.realloc( n_ConstDigestLength );
++
++    uno::Sequence< sal_Int8 > aDigestSeq;
++    uno::Reference< xml::crypto::XDigestContext > xDigestContext( StaticGetDigestContextForChecksum( xFactory, rData ), uno::UNO_SET_THROW );
+ 
+-    aDigestResult = rtl_digest_getSHA1 ( aDigest, aDigestSeq.getArray(), RTL_DIGEST_LENGTH_SHA1 );
+-    OSL_ASSERT ( aDigestResult == rtl_Digest_E_None );
+-    (void)aDigestResult;
++    xDigestContext->updateDigest( aDecryptBuffer );
++    aDigestSeq = xDigestContext->finalizeDigestAndDispose();
+ 
+     // If we don't have a digest, then we have to assume that the password is correct
+-    if (  rData->aDigest.getLength() != 0  &&
+-          ( aDigestSeq.getLength() != rData->aDigest.getLength() ||
++    if (  rData->m_aDigest.getLength() != 0  &&
++          ( aDigestSeq.getLength() != rData->m_aDigest.getLength() ||
+             0 != rtl_compareMemory ( aDigestSeq.getConstArray(),
+-                                     rData->aDigest.getConstArray(),
++                                     rData->m_aDigest.getConstArray(),
+                                     aDigestSeq.getLength() ) ) )
+     {
+         // We should probably tell the user that the password they entered was wrong
+@@ -373,8 +513,6 @@ sal_Bool ZipFile::StaticHasValidPassword( const Sequence< sal_Int8 > &aReadBuffe
+     else
+         bRet = sal_True;
+ 
+-    rtl_digest_destroySHA1 ( aDigest );
+-
+     return bRet;
+ }
+ 
+@@ -383,18 +521,20 @@ sal_Bool ZipFile::hasValidPassword ( ZipEntry & rEntry, const rtl::Reference < E
+     ::osl::MutexGuard aGuard( m_aMutex );
+ 
+     sal_Bool bRet = sal_False;
+-    if ( rData->aKey.getLength() )
++    if ( rData.is() && rData->m_aKey.getLength() )
+     {
+         xSeek->seek( rEntry.nOffset );
+         sal_Int32 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize;
+ 
+         // Only want to read enough to verify the digest
+-        nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
++        if ( nSize > n_ConstDigestDecrypt )
++            nSize = n_ConstDigestDecrypt;
++
+         Sequence < sal_Int8 > aReadBuffer ( nSize );
+ 
+         xStream->readBytes( aReadBuffer, nSize );
+ 
+-        bRet = StaticHasValidPassword( aReadBuffer, rData );
++        bRet = StaticHasValidPassword( m_xFactory, aReadBuffer, rData );
+     }
+     return bRet;
+ }
+@@ -502,7 +642,7 @@ Reference < XInputStream > ZipFile::createUnbufferedStream(
+ {
+     ::osl::MutexGuard aGuard( m_aMutex );
+ 
+-    return new XUnbufferedStream ( aMutexHolder, rEntry, xStream, rData, nStreamMode, bIsEncrypted, aMediaType, bRecoveryMode );
++    return new XUnbufferedStream ( m_xFactory, aMutexHolder, rEntry, xStream, rData, nStreamMode, bIsEncrypted, aMediaType, bRecoveryMode );
+ }
+ 
+ 
+@@ -512,7 +652,7 @@ ZipEnumeration * SAL_CALL ZipFile::entries(  )
+ }
+ 
+ Reference< XInputStream > SAL_CALL ZipFile::getInputStream( ZipEntry& rEntry,
+-        const rtl::Reference < EncryptionData > &rData,
++        const rtl::Reference< EncryptionData > &rData,
+         sal_Bool bIsEncrypted,
+         SotMutexHolderRef aMutexHolder )
+     throw(IOException, ZipException, RuntimeException)
+@@ -529,7 +669,7 @@ Reference< XInputStream > SAL_CALL ZipFile::getInputStream( ZipEntry& rEntry,
+ 
+     // if we have a digest, then this file is an encrypted one and we should
+     // check if we can decrypt it or not
+-    if ( bIsEncrypted && rData.is() && rData->aDigest.getLength() )
++    if ( bIsEncrypted && rData.is() && rData->m_aDigest.getLength() )
+         bNeedRawStream = !hasValidPassword ( rEntry, rData );
+ 
+     return createUnbufferedStream ( aMutexHolder,
+@@ -540,7 +680,7 @@ Reference< XInputStream > SAL_CALL ZipFile::getInputStream( ZipEntry& rEntry,
+ }
+ 
+ Reference< XInputStream > SAL_CALL ZipFile::getDataStream( ZipEntry& rEntry,
+-        const rtl::Reference < EncryptionData > &rData,
++        const rtl::Reference< EncryptionData > &rData,
+         sal_Bool bIsEncrypted,
+         SotMutexHolderRef aMutexHolder )
+     throw ( packages::WrongPasswordException,
+@@ -566,8 +706,8 @@ Reference< XInputStream > SAL_CALL ZipFile::getDataStream( ZipEntry& rEntry,
+ 
+         // if we have a digest, then this file is an encrypted one and we should
+         // check if we can decrypt it or not
+-        OSL_ENSURE( rData->aDigest.getLength(), "Can't detect password correctness without digest!\n" );
+-        if ( rData->aDigest.getLength() && !hasValidPassword ( rEntry, rData ) )
++        OSL_ENSURE( rData->m_aDigest.getLength(), "Can't detect password correctness without digest!\n" );
++        if ( rData->m_aDigest.getLength() && !hasValidPassword ( rEntry, rData ) )
+                 throw packages::WrongPasswordException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+     }
+     else
+diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
+index 1d29e17..26c468d 100644
+--- a/package/source/zipapi/ZipOutputStream.cxx
++++ b/package/source/zipapi/ZipOutputStream.cxx
+@@ -39,7 +39,9 @@
+ #include <com/sun/star/io/XOutputStream.hpp>
+ 
+ #include <comphelper/storagehelper.hxx>
++#include <ZipPackageStream.hxx>
+ 
++using namespace com::sun::star;
+ using namespace com::sun::star::io;
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star::packages;
+@@ -48,17 +50,18 @@ using namespace com::sun::star::packages::zip::ZipConstants;
+ 
+ /** This class is used to write Zip files
+  */
+-ZipOutputStream::ZipOutputStream( Reference < XOutputStream > &xOStream )
+-: xStream(xOStream)
+-, aBuffer(n_ConstBufferSize)
++ZipOutputStream::ZipOutputStream( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
++                                  const uno::Reference < XOutputStream > &xOStream )
++: m_xFactory( xFactory )
++, xStream(xOStream)
++, m_aDeflateBuffer(n_ConstBufferSize)
+ , aDeflater(DEFAULT_COMPRESSION, sal_True)
+ , aChucker(xOStream)
+ , pCurrentEntry(NULL)
+ , nMethod(DEFLATED)
+ , bFinished(sal_False)
+ , bEncryptCurrentEntry(sal_False)
+-
+-
++, m_pCurrentStream(NULL)
+ {
+ }
+ 
+@@ -80,7 +83,7 @@ void SAL_CALL ZipOutputStream::setLevel( sal_Int32 nNewLevel )
+ }
+ 
+ void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry, 
+-                        rtl::Reference < EncryptionData > &xEncryptData,
++                        ZipPackageStream* pStream,
+                         sal_Bool bEncrypt)
+     throw(IOException, RuntimeException)
+ {
+@@ -94,18 +97,20 @@ void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry,
+     rEntry.nFlag = 1 << 11;
+     if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
+         rEntry.nCrc == -1)
++    {
++        rEntry.nSize = rEntry.nCompressedSize = 0;
+         rEntry.nFlag |= 8;
++    }
+ 
+     if (bEncrypt)
+     {
+         bEncryptCurrentEntry = sal_True;
+ 
+-        ZipFile::StaticGetCipher( xEncryptData, aCipher, sal_False );
+-
+-        aDigest = rtl_digest_createSHA1();
++        m_xCipherContext = ZipFile::StaticGetCipher( m_xFactory, pStream->GetEncryptionData(), true );
++        m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( m_xFactory, pStream->GetEncryptionData() );
+         mnDigested = 0;
+         rEntry.nFlag |= 1 << 4;
+-        pCurrentEncryptData = xEncryptData.get();
++        m_pCurrentStream = pStream;
+     }
+     sal_Int32 nLOCLength = writeLOC(rEntry);
+     rEntry.nOffset = static_cast < sal_Int32 > (aChucker.GetPosition()) - nLOCLength;
+@@ -144,11 +149,12 @@ void SAL_CALL ZipOutputStream::closeEntry(  )
+                 }
+                 else
+                 {
++                    if ( !bEncryptCurrentEntry )
++                    {
+                     pEntry->nSize = aDeflater.getTotalIn();
+                     pEntry->nCompressedSize = aDeflater.getTotalOut();
++                    }
+                     pEntry->nCrc = aCRC.getValue();
+-                    if ( bEncryptCurrentEntry )
+-                        pEntry->nSize = pEntry->nCompressedSize;
+                     writeEXT(*pEntry);
+                 }
+                 aDeflater.reset();
+@@ -165,19 +171,22 @@ void SAL_CALL ZipOutputStream::closeEntry(  )
+ 
+         if (bEncryptCurrentEntry)
+         {
+-            rtlDigestError aDigestResult;
+-            aEncryptionBuffer.realloc ( 0 );
+             bEncryptCurrentEntry = sal_False;
+-            rtl_cipher_destroy ( aCipher );
+-            pCurrentEncryptData->aDigest.realloc ( RTL_DIGEST_LENGTH_SHA1 );
+-            aDigestResult = rtl_digest_getSHA1 ( aDigest, 
+-                                                 reinterpret_cast < sal_uInt8 * > ( pCurrentEncryptData->aDigest.getArray() ),
+-                                                 RTL_DIGEST_LENGTH_SHA1 );
+-            OSL_ASSERT( aDigestResult == rtl_Digest_E_None );
+-            (void)aDigestResult;
+-            rtl_digest_destroySHA1 ( aDigest );
++
++            m_xCipherContext.clear();
++
++            uno::Sequence< sal_Int8 > aDigestSeq;
++            if ( m_xDigestContext.is() )
++            {
++                aDigestSeq = m_xDigestContext->finalizeDigestAndDispose();
++                m_xDigestContext.clear();
++            }
++
++            if ( m_pCurrentStream )
++                m_pCurrentStream->setDigest( aDigestSeq );
+         }
+         pCurrentEntry = NULL;
++        m_pCurrentStream = NULL;
+     }
+ }
+ 
+@@ -242,42 +251,51 @@ void SAL_CALL ZipOutputStream::finish(  )
+ 
+ void ZipOutputStream::doDeflate()
+ {
+-    sal_Int32 nLength = aDeflater.doDeflateSegment(aBuffer, 0, aBuffer.getLength());
+-    sal_Int32 nOldLength = aBuffer.getLength();
++    sal_Int32 nLength = aDeflater.doDeflateSegment(m_aDeflateBuffer, 0, m_aDeflateBuffer.getLength());
+ 
+     if ( nLength > 0 )
+     {
+-        Sequence < sal_Int8 > aTmpBuffer ( aBuffer.getConstArray(), nLength );
+-        const void *pTmpBuffer = static_cast < const void * > ( aTmpBuffer.getConstArray() );
+-        if (bEncryptCurrentEntry)
++        Sequence< sal_Int8 > aTmpBuffer ( m_aDeflateBuffer.getConstArray(), nLength );
++        if (bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is())
+         {
+             // Need to update our digest before encryption...
+-            rtlDigestError aDigestResult = rtl_Digest_E_None;
+-            sal_Int16 nDiff = n_ConstDigestLength - mnDigested;
++            sal_Int32 nDiff = n_ConstDigestLength - mnDigested;
+             if ( nDiff )
+             {
+-                sal_Int16 nEat = static_cast < sal_Int16 > ( nDiff > nLength ? nLength : nDiff );
+-                aDigestResult = rtl_digest_updateSHA1 ( aDigest, pTmpBuffer, nEat );
+-                mnDigested = mnDigested + nEat;
++                sal_Int32 nEat = ::std::min( nLength, nDiff );
++                uno::Sequence< sal_Int8 > aTmpSeq( aTmpBuffer.getConstArray(), nEat );
++                m_xDigestContext->updateDigest( aTmpSeq );
++                mnDigested = mnDigested + static_cast< sal_Int16 >( nEat );
+             }
+-            OSL_ASSERT( aDigestResult == rtl_Digest_E_None );
+-            (void)aDigestResult;
+-
+-            aEncryptionBuffer.realloc ( nLength );
+ 
+-            rtlCipherError aCipherResult;
+-            aCipherResult = rtl_cipher_encode ( aCipher, pTmpBuffer,
+-                                            nLength, reinterpret_cast < sal_uInt8 * > (aEncryptionBuffer.getArray()),  nLength );
+-            OSL_ASSERT( aCipherResult == rtl_Cipher_E_None );
+-            (void)aCipherResult;
++            uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer );
+ 
+             aChucker.WriteBytes( aEncryptionBuffer );
++
++            // the sizes as well as checksum for encrypted streams is calculated here
++            pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
++            pCurrentEntry->nSize = pCurrentEntry->nCompressedSize;
+             aCRC.update ( aEncryptionBuffer );
+-            aEncryptionBuffer.realloc ( nOldLength );
+         }
+         else
++        {
+             aChucker.WriteBytes ( aTmpBuffer );
+     }
++    }
++
++    if ( aDeflater.finished() && bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() )
++    {
++        uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose();
++        if ( aEncryptionBuffer.getLength() )
++        {
++            aChucker.WriteBytes( aEncryptionBuffer );
++
++            // the sizes as well as checksum for encrypted streams is calculated hier
++            pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
++            pCurrentEntry->nSize = pCurrentEntry->nCompressedSize;
++            aCRC.update( aEncryptionBuffer );
++        }
++    }
+ }
+ void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
+     throw(IOException, RuntimeException)
+diff --git a/package/source/zipapi/blowfishcontext.cxx b/package/source/zipapi/blowfishcontext.cxx
+new file mode 100644
+index 0000000..1739bb1
+--- /dev/null
++++ b/package/source/zipapi/blowfishcontext.cxx
+@@ -0,0 +1,122 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_package.hxx"
++
++#include <rtl/cipher.h>
++#include <rtl/ref.hxx>
++
++#include "blowfishcontext.hxx"
++
++using namespace ::com::sun::star;
++
++// static
++uno::Reference< xml::crypto::XCipherContext > BlowfishCFB8CipherContext::Create( const uno::Sequence< sal_Int8 >& aDerivedKey, const uno::Sequence< sal_Int8 >& aInitVector, bool bEncrypt )
++{
++    ::rtl::Reference< BlowfishCFB8CipherContext > xResult = new BlowfishCFB8CipherContext();
++    xResult->m_pCipher = rtl_cipher_create( rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
++    if ( !xResult->m_pCipher )
++        throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can not create cipher!\n" ),
++                                     uno::Reference< XInterface >() );
++
++    if ( rtl_Cipher_E_None != rtl_cipher_init(
++                                xResult->m_pCipher,
++                                bEncrypt ? rtl_Cipher_DirectionEncode : rtl_Cipher_DirectionDecode,
++                                reinterpret_cast< const sal_uInt8* >( aDerivedKey.getConstArray() ),
++                                aDerivedKey.getLength(),
++                                reinterpret_cast< const sal_uInt8* >( aInitVector.getConstArray() ),
++                                aInitVector.getLength() ) )
++    {
++        throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can not initialize cipher!\n" ),
++                                     uno::Reference< XInterface >() );
++    }
++
++    xResult->m_bEncrypt = bEncrypt;
++
++    return uno::Reference< xml::crypto::XCipherContext >( xResult.get() );
++}
++
++BlowfishCFB8CipherContext::~BlowfishCFB8CipherContext()
++{
++    if ( m_pCipher )
++    {
++        rtl_cipher_destroy ( m_pCipher );
++        m_pCipher = NULL;
++    }
++}
++
++uno::Sequence< sal_Int8 > SAL_CALL BlowfishCFB8CipherContext::convertWithCipherContext( const uno::Sequence< ::sal_Int8 >& aData )
++    throw( lang::IllegalArgumentException, lang::DisposedException, uno::RuntimeException )
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++    if ( !m_pCipher )
++        throw lang::DisposedException();
++
++    uno::Sequence< sal_Int8 > aResult( aData.getLength() );
++    rtlCipherError nError = rtl_Cipher_E_None;
++
++    if ( m_bEncrypt )
++    {
++        rtl_cipher_encode( m_pCipher,
++                          aData.getConstArray(),
++                          aData.getLength(),
++                          reinterpret_cast< sal_uInt8* >( aResult.getArray() ),
++                          aResult.getLength() );
++    }
++    else
++    {
++        rtl_cipher_decode( m_pCipher,
++                          aData.getConstArray(),
++                          aData.getLength(),
++                          reinterpret_cast< sal_uInt8* >( aResult.getArray() ),
++                          aResult.getLength() );
++    }
++
++    if ( rtl_Cipher_E_None != nError )
++    {
++        throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can not decrypt/encrypt with cipher!\n" ),
++                                     uno::Reference< uno::XInterface >() );
++    }
++
++    return aResult;
++}
++
++uno::Sequence< ::sal_Int8 > SAL_CALL BlowfishCFB8CipherContext::finalizeCipherContextAndDispose()
++    throw( lang::DisposedException, uno::RuntimeException )
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++    if ( !m_pCipher )
++        throw lang::DisposedException();
++
++    rtl_cipher_destroy ( m_pCipher );
++    m_pCipher = NULL;
++
++    return uno::Sequence< sal_Int8 >();
++}
++
++
+diff --git a/package/source/zipapi/blowfishcontext.hxx b/package/source/zipapi/blowfishcontext.hxx
+new file mode 100644
+index 0000000..49cce2f
+--- /dev/null
++++ b/package/source/zipapi/blowfishcontext.hxx
+@@ -0,0 +1,58 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef _BLOWFISHCONTEXT_HXX
++#define _BLOWFISHCONTEXT_HXX
++
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++
++#include <cppuhelper/implbase1.hxx>
++#include <osl/mutex.hxx>
++
++class BlowfishCFB8CipherContext : public cppu::WeakImplHelper1< ::com::sun::star::xml::crypto::XCipherContext >
++{
++    ::osl::Mutex m_aMutex;
++    void* m_pCipher;
++    bool m_bEncrypt;
++
++    BlowfishCFB8CipherContext()
++    : m_pCipher( NULL )
++    , m_bEncrypt( false )
++    {}
++
++public:
++
++    virtual ~BlowfishCFB8CipherContext();
++
++    static ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext >
++        Create( const ::com::sun::star::uno::Sequence< sal_Int8 >& aDerivedKey, const ::com::sun::star::uno::Sequence< sal_Int8 >& aInitVector, bool bEncrypt );
++
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL convertWithCipherContext( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL finalizeCipherContextAndDispose(  ) throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++};
++
++#endif // _BLOWFISHCONTEXT_HXX
++
+diff --git a/package/source/zipapi/makefile.mk b/package/source/zipapi/makefile.mk
+index ec8d636..8a07d44 100644
+--- a/package/source/zipapi/makefile.mk
++++ b/package/source/zipapi/makefile.mk
+@@ -46,8 +46,10 @@ SLOFILES= \
+         $(SLO)$/CRC32.obj			\
+         $(SLO)$/ByteChucker.obj		\
+         $(SLO)$/ByteGrabber.obj		\
++        $(SLO)$/blowfishcontext.obj	\
+         $(SLO)$/Inflater.obj		\
+         $(SLO)$/Deflater.obj		\
++        $(SLO)$/sha1context.obj		\
+         $(SLO)$/ZipEnumeration.obj	\
+         $(SLO)$/ZipFile.obj			\
+         $(SLO)$/ZipOutputStream.obj	\
+diff --git a/package/source/zipapi/sha1context.cxx b/package/source/zipapi/sha1context.cxx
+new file mode 100644
+index 0000000..a71f20a
+--- /dev/null
++++ b/package/source/zipapi/sha1context.cxx
+@@ -0,0 +1,97 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_package.hxx"
++
++#include <rtl/digest.h>
++#include <rtl/ref.hxx>
++
++#include "sha1context.hxx"
++
++using namespace ::com::sun::star;
++
++// static
++uno::Reference< xml::crypto::XDigestContext > SHA1DigestContext::Create()
++{
++    ::rtl::Reference< SHA1DigestContext > xResult = new SHA1DigestContext();
++    xResult->m_pDigest = rtl_digest_createSHA1();
++    if ( !xResult->m_pDigest )
++        throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can not create cipher!\n" ),
++                                     uno::Reference< XInterface >() );
++
++    return uno::Reference< xml::crypto::XDigestContext >( xResult.get() );
++}
++
++SHA1DigestContext::~SHA1DigestContext()
++{
++    if ( m_pDigest )
++    {
++        rtl_digest_destroySHA1( m_pDigest );
++        m_pDigest = NULL;
++    }
++}
++
++void SAL_CALL SHA1DigestContext::updateDigest( const uno::Sequence< ::sal_Int8 >& aData )
++    throw( lang::DisposedException, uno::RuntimeException )
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++    if ( !m_pDigest )
++        throw lang::DisposedException();
++
++    if ( rtl_Digest_E_None != rtl_digest_updateSHA1( m_pDigest, aData.getConstArray(), aData.getLength() ) )
++    {
++        rtl_digest_destroySHA1( m_pDigest );
++        m_pDigest = NULL;
++
++        throw uno::RuntimeException();
++    }
++}
++
++uno::Sequence< ::sal_Int8 > SAL_CALL SHA1DigestContext::finalizeDigestAndDispose()
++    throw( lang::DisposedException, uno::RuntimeException )
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++    if ( !m_pDigest )
++        throw lang::DisposedException();
++
++    uno::Sequence< sal_Int8 > aResult( RTL_DIGEST_LENGTH_SHA1 );
++    if ( rtl_Digest_E_None != rtl_digest_getSHA1( m_pDigest, reinterpret_cast< sal_uInt8* >( aResult.getArray() ), aResult.getLength() ) )
++    {
++        rtl_digest_destroySHA1( m_pDigest );
++        m_pDigest = NULL;
++
++        throw uno::RuntimeException();
++    }
++
++    rtl_digest_destroySHA1( m_pDigest );
++    m_pDigest = NULL;
++
++    return aResult;
++}
++
++
+diff --git a/package/source/zipapi/sha1context.hxx b/package/source/zipapi/sha1context.hxx
+new file mode 100644
+index 0000000..dbd1207
+--- /dev/null
++++ b/package/source/zipapi/sha1context.hxx
+@@ -0,0 +1,57 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef _SHA1CONTEXT_HXX
++#define _SHA1CONTEXT_HXX
++
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++
++#include <cppuhelper/implbase1.hxx>
++#include <osl/mutex.hxx>
++
++class SHA1DigestContext : public cppu::WeakImplHelper1< ::com::sun::star::xml::crypto::XDigestContext >
++{
++    ::osl::Mutex m_aMutex;
++    void* m_pDigest;
++
++    SHA1DigestContext()
++    : m_pDigest( NULL )
++    {}
++
++public:
++
++    virtual ~SHA1DigestContext();
++
++    static ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext >
++        Create();
++
++    virtual void SAL_CALL updateDigest( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL finalizeDigestAndDispose() throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++
++};
++
++#endif // _SHA1CONTEXT_HXX
++
+diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
+index 1f1e48a..b4809a0 100644
+--- a/package/source/zippackage/ZipPackage.cxx
++++ b/package/source/zippackage/ZipPackage.cxx
+@@ -63,6 +63,8 @@
+ #include <com/sun/star/embed/UseBackupException.hpp>
+ #include <com/sun/star/embed/StorageFormats.hpp>
+ #include <com/sun/star/beans/NamedValue.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
+ #include <cppuhelper/implbase1.hxx>
+ #include <ContentInfo.hxx>
+ #include <cppuhelper/typeprovider.hxx>
+@@ -83,6 +85,7 @@
+ #include <comphelper/storagehelper.hxx>
+ #include <comphelper/ofopxmlhelper.hxx>
+ #include <comphelper/documentconstants.hxx>
++#include <comphelper/sequenceashashmap.hxx>
+ 
+ using namespace std;
+ using namespace osl;
+@@ -181,10 +184,12 @@ class DummyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
+ 
+ ZipPackage::ZipPackage (const uno::Reference < XMultiServiceFactory > &xNewFactory)
+ : m_aMutexHolder( new SotMutexHolder )
++, m_nStartKeyGenerationID( xml::crypto::DigestID::SHA1 )
++, m_nChecksumDigestID( xml::crypto::DigestID::SHA1_1K )
++, m_nCommonEncryptionID( xml::crypto::CipherID::BLOWFISH_CFB_8 )
+ , m_bHasEncryptedEntries ( sal_False )
+ , m_bHasNonEncryptedEntries ( sal_False )
+ , m_bInconsistent ( sal_False )
+-, m_bUseManifest ( sal_True )
+ , m_bForceRecovery ( sal_False )
+ , m_bMediaTypeFallbackUsed ( sal_False )
+ , m_nFormat( embed::StorageFormats::PACKAGE ) // package is the default format
+@@ -224,6 +229,7 @@ void ZipPackage::parseManifest()
+     if ( m_nFormat == embed::StorageFormats::PACKAGE )
+     {
+         sal_Bool bManifestParsed = sal_False;
++        bool bDifferentStartKeyAlgorithm = false;
+         const OUString sMeta ( RTL_CONSTASCII_USTRINGPARAM ( "META-INF" ) );
+         if ( m_xRootFolder->hasByName( sMeta ) )
+         {
+@@ -253,6 +259,10 @@ void ZipPackage::parseManifest()
+                             const OUString sPropIterationCount ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+                             const OUString sPropSize ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+                             const OUString sPropDigest ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
++                            const OUString sPropDerivedKeySize ( RTL_CONSTASCII_USTRINGPARAM ( "DerivedKeySize" ) );
++                            const OUString sPropDigestAlgorithm ( RTL_CONSTASCII_USTRINGPARAM ( "DigestAlgorithm" ) );
++                            const OUString sPropEncryptionAlgorithm ( RTL_CONSTASCII_USTRINGPARAM ( "EncryptionAlgorithm" ) );
++                            const OUString sPropStartKeyAlgorithm ( RTL_CONSTASCII_USTRINGPARAM ( "StartKeyAlgorithm" ) );
+                             
+                             Sequence < Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() );
+                             sal_Int32 nLength = aManifestSequence.getLength();
+@@ -264,7 +274,7 @@ void ZipPackage::parseManifest()
+                             {
+                                 OUString sPath, sMediaType, sVersion;
+                                 const PropertyValue *pValue = pSequence->getConstArray();
+-                                const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL;
++                                const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL, *pDigestAlg = NULL, *pEncryptionAlg = NULL, *pStartKeyAlg = NULL, *pDerivedKeySize = NULL;
+                                 for (sal_Int32 j = 0, nNum = pSequence->getLength(); j < nNum; j++ )
+                                 {
+                                     if (pValue[j].Name.equals( sPropFullPath ) )
+@@ -283,6 +293,14 @@ void ZipPackage::parseManifest()
+                                         pSize = &(pValue[j].Value);
+                                     else if (pValue[j].Name.equals( sPropDigest ) )
+                                         pDigest = &(pValue[j].Value);
++                                    else if ( pValue[j].Name.equals( sPropDigestAlgorithm ) )
++                                        pDigestAlg = &( pValue[j].Value );
++                                    else if ( pValue[j].Name.equals( sPropEncryptionAlgorithm ) )
++                                        pEncryptionAlg = &( pValue[j].Value );
++                                    else if ( pValue[j].Name.equals( sPropStartKeyAlgorithm ) )
++                                        pStartKeyAlg = &( pValue[j].Value );
++                                    else if ( pValue[j].Name.equals( sPropDerivedKeySize ) )
++                                        pDerivedKeySize = &( pValue[j].Value );
+                                 }
+ 
+                                 if (sPath.getLength() && hasByHierarchicalName ( sPath ) )
+@@ -303,10 +321,10 @@ void ZipPackage::parseManifest()
+                                         pStream->SetMediaType ( sMediaType );
+                                         pStream->SetFromManifest( sal_True );
+             
+-                                        if (pSalt && pVector && pCount && pSize)
++                                        if (pSalt && pVector && pCount && pSize && pDigest && pDigestAlg && pEncryptionAlg )
+                                         {
+-                                            Sequence < sal_uInt8 > aSequence;
+-                                            sal_Int32 nCount = 0, nSize = 0;
++                                            Sequence < sal_Int8 > aSequence;
++                                            sal_Int32 nCount = 0, nSize = 0, nDigestAlg = 0, nEncryptionAlg = 0, nDerivedKeySize = 16, nStartKeyAlg = xml::crypto::DigestID::SHA1;
+                                                                            pStream->SetToBeEncrypted ( sal_True );
+             
+                                             *pSalt >>= aSequence;
+@@ -321,18 +339,34 @@ void ZipPackage::parseManifest()
+                                             *pSize >>= nSize;
+                                             pStream->setSize ( nSize );
+             
+-                                            if ( pDigest )
+-                                            {
+-                                                *pDigest >>= aSequence;
+-                                                pStream->setDigest ( aSequence );
+-                                            }
++                                            *pDigest >>= aSequence;
++                                            pStream->setDigest ( aSequence );
++
++                                            *pDigestAlg >>= nDigestAlg;
++                                            pStream->SetImportedChecksumAlgorithm( nDigestAlg );
++
++                                            *pEncryptionAlg >>= nEncryptionAlg;
++                                            pStream->SetImportedEncryptionAlgorithm( nEncryptionAlg );
++
++                                            if ( pDerivedKeySize )
++                                                *pDerivedKeySize >>= nDerivedKeySize;
++                                            pStream->SetImportedDerivedKeySize( nDerivedKeySize );
++
++                                            if ( pStartKeyAlg )
++                                                *pStartKeyAlg >>= nStartKeyAlg;
++                                            pStream->SetImportedStartKeyAlgorithm( nStartKeyAlg );
+             
+                                             pStream->SetToBeCompressed ( sal_True );
+                                             pStream->SetToBeEncrypted ( sal_True );
+                                             pStream->SetIsEncrypted ( sal_True );
+                                             if ( !m_bHasEncryptedEntries
+                                               && pStream->getName().equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ) ) )
++                                            {
+                                                 m_bHasEncryptedEntries = sal_True;
++                                                m_nStartKeyGenerationID = nStartKeyAlg;
++                                                m_nChecksumDigestID = nDigestAlg;
++                                                m_nCommonEncryptionID = nEncryptionAlg;
++                                            }
+                                         }
+                                         else
+                                             m_bHasNonEncryptedEntries = sal_True;
+@@ -411,20 +445,30 @@ void ZipPackage::parseManifest()
+ 
+         m_bInconsistent = m_pRootFolder->LookForUnexpectedODF12Streams( ::rtl::OUString() );
+ 
+-        sal_Bool bODF12AndOlder = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
+-        if ( !m_bForceRecovery && bODF12AndOlder && m_bInconsistent )
++        sal_Bool bODF12AndNewer = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
++        if ( !m_bForceRecovery && bODF12AndNewer )
+         {
+-            // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
+-            // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
+-            // should be checked later
+-            throw ZipIOException(
+-                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n" ) ),
+-                uno::Reference< uno::XInterface >() );
++            if ( m_bInconsistent )
++            {
++                // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
++                // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
++                // should be checked later
++                throw ZipIOException(
++                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n" ) ),
++                    uno::Reference< uno::XInterface >() );
++            }
++            else if ( bDifferentStartKeyAlgorithm )
++            {
++                // all the streams should be encrypted with the same StartKey in ODF1.2
++                // TODO/LATER: in future the exception should be thrown
++                OSL_ENSURE( false, "ODF1.2 contains different StartKey Algorithms" );
++                // throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "More than one Start Key Generation algorithm is specified!" ) ), uno::Reference< uno::XInterface >() );
++            }
+         }
+ 
+         // in case it is a correct ODF1.2 document, the version must be set
+         // and the META-INF folder is reserved for package format
+-        if ( bODF12AndOlder )
++        if ( bODF12AndNewer )
+             m_xRootFolder->removeByName( sMeta );
+     }
+ }
+@@ -981,14 +1025,12 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
+ 
+     try
+     {
+-        rtl::Reference < EncryptionData > xEmpty;
+-        aZipOut.putNextEntry( *pEntry, xEmpty );
++        aZipOut.putNextEntry( *pEntry, NULL );
+         aZipOut.write( aType, 0, nBufferLength );
+         aZipOut.closeEntry();
+     }
+     catch ( ::com::sun::star::io::IOException & r )
+     {
+-        OSL_FAIL( "Error adding mimetype to the ZipOutputStream" );
+         throw WrappedTargetException( 
+                 OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Error adding mimetype to the ZipOutputStream!" ) ),
+                 static_cast < OWeakObject * > ( this ), 
+@@ -1015,19 +1057,20 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< Sequence
+ 
+         // Convert vector into a Sequence
+         Sequence < Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
+-        Sequence < PropertyValue > * pSequence = aManifestSequence.getArray();
++        sal_Int32 nInd = 0;
+         for (vector < Sequence < PropertyValue > >::const_iterator aIter = aManList.begin(), aEnd = aManList.end();
+              aIter != aEnd;
+-             ++aIter, ++pSequence)
+-            *pSequence= (*aIter);
++             aIter++, nInd++ )
++        {
++            aManifestSequence[nInd] = ( *aIter );
++        }
+         xWriter->writeManifestSequence ( xManOutStream,  aManifestSequence );
+ 
+         sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
+         pBuffer->realloc( nBufferLength );
+ 
+         // the manifest.xml is never encrypted - so pass an empty reference
+-                rtl::Reference < EncryptionData > xEmpty;
+-        aZipOut.putNextEntry( *pEntry, xEmpty );
++        aZipOut.putNextEntry( *pEntry, NULL );
+         aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
+         aZipOut.closeEntry();
+     }
+@@ -1089,8 +1132,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< Sequ
+     pBuffer->realloc( nBufferLength );
+ 
+     // there is no encryption in this format currently
+-            rtl::Reference < EncryptionData > xEmpty;
+-    aZipOut.putNextEntry( *pEntry, xEmpty );
++    aZipOut.putNextEntry( *pEntry, NULL );
+     aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
+     aZipOut.closeEntry();
+ }
+@@ -1154,7 +1196,7 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
+     }
+     
+     // Hand it to the ZipOutputStream:
+-    ZipOutputStream aZipOut ( xTempOut );
++    ZipOutputStream aZipOut ( m_xFactory, xTempOut );
+     aZipOut.setMethod(DEFLATED);
+     aZipOut.setLevel(DEFAULT_COMPRESSION);
+ 
+@@ -1224,12 +1266,12 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
+     
+         // call saveContents (it will recursively save sub-directories
+         OUString aEmptyString;
+-        m_pRootFolder->saveContents( aEmptyString, aManList, aZipOut, m_aEncryptionKey, aRandomPool );
++        m_pRootFolder->saveContents( aEmptyString, aManList, aZipOut, GetEncryptionKey(), aRandomPool );
+     
+         // Clean up random pool memory
+         rtl_random_destroyPool ( aRandomPool );
+ 
+-        if( m_bUseManifest && m_nFormat == embed::StorageFormats::PACKAGE )
++        if( m_nFormat == embed::StorageFormats::PACKAGE )
+         {
+             WriteManifest( aZipOut, aManList );
+         }
+@@ -1549,6 +1591,36 @@ void ZipPackage::DisconnectFromTargetAndThrowException_Impl( const uno::Referenc
+                                     makeAny ( aException ) );
+ }
+ 
++//--------------------------------------------------------
++const uno::Sequence< sal_Int8 > ZipPackage::GetEncryptionKey()
++{
++    uno::Sequence< sal_Int8 > aResult;
++
++    if ( m_aStorageEncryptionKeys.getLength() )
++    {
++        ::rtl::OUString aNameToFind;
++        if ( m_nStartKeyGenerationID == xml::crypto::DigestID::SHA256 )
++            aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
++        else if ( m_nStartKeyGenerationID == xml::crypto::DigestID::SHA1 )
++            aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
++        else
++            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );
++
++        for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
++            if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) )
++                m_aStorageEncryptionKeys[nInd].Value >>= aResult;
++
++        // empty keys are not allowed here
++        // so it is not important whether there is no key, or the key is empty, it is an error
++        if ( !aResult.getLength() )
++            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );
++    }
++    else
++        aResult = m_aEncryptionKey;
++
++    return aResult;
++}
++
+ sal_Bool SAL_CALL ZipPackage::hasPendingChanges(  ) 
+         throw(RuntimeException)
+ {
+@@ -1639,20 +1711,91 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const
+     if ( m_nFormat != embed::StorageFormats::PACKAGE )
+         throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+-    if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("HasEncryptedEntries") )
+-      ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("HasNonEncryptedEntries") )
+-      ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("IsInconsistent") )
+-      ||aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaTypeFallbackUsed") ) )
++    if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( HAS_ENCRYPTED_ENTRIES_PROPERTY ) )
++      ||aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( HAS_NONENCRYPTED_ENTRIES_PROPERTY ) )
++      ||aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( IS_INCONSISTENT_PROPERTY ) )
++      ||aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MEDIATYPE_FALLBACK_USED_PROPERTY ) ) )
+         throw PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+-    else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) )
++    else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) )
+     {
+-        if (!( aValue >>= m_aEncryptionKey ) || m_aEncryptionKey.getLength() == 0 )
++        if (!( aValue >>= m_aEncryptionKey ) )
+             throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
++
++        m_aStorageEncryptionKeys.realloc( 0 );
+     }
+-    else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UseManifest") ) )
++    else if (aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
+     {
+-        if (!( aValue >>= m_bUseManifest ) )
++        // this property is only necessary to support raw passwords in storage API;
++        // because of this support the storage has to operate with more than one key dependent on storage generation algorithm;
++        // when this support is removed, the storage will get only one key from outside
++        // TODO/LATER: Get rid of this property as well as of support of raw passwords in storages
++        uno::Sequence< beans::NamedValue > aKeys;
++        if ( !( aValue >>= aKeys ) || ( aKeys.getLength() && aKeys.getLength() < 2 ) )
+             throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
++
++        if ( aKeys.getLength() )
++        {
++            bool bHasSHA256 = false;
++            bool bHasSHA1 = false;
++            for ( sal_Int32 nInd = 0; nInd < aKeys.getLength(); nInd++ )
++            {
++                if ( aKeys[nInd].Name.equals( PACKAGE_ENCRYPTIONDATA_SHA256UTF8 ) )
++                    bHasSHA256 = true;
++                if ( aKeys[nInd].Name.equals( PACKAGE_ENCRYPTIONDATA_SHA1UTF8 ) )
++                    bHasSHA1 = true;
++            }
++
++            if ( !bHasSHA256 || !bHasSHA1 )
++                throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Expected keys are not provided!" ) ), uno::Reference< uno::XInterface >(), 2 );
++        }
++
++        m_aStorageEncryptionKeys = aKeys;
++        m_aEncryptionKey.realloc( 0 );
++    }
++    else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) )
++    {
++        uno::Sequence< beans::NamedValue > aAlgorithms;
++        if ( m_pZipFile || !( aValue >>= aAlgorithms ) || aAlgorithms.getLength() == 0 )
++        {
++            // the algorithms can not be changed if the file has a persistence based on the algorithms ( m_pZipFile )
++            throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "unexpected algorithms list is provided." ) ), uno::Reference< uno::XInterface >(), 2 );
++        }
++
++        for ( sal_Int32 nInd = 0; nInd < aAlgorithms.getLength(); nInd++ )
++        {
++            if ( aAlgorithms[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StartKeyGenerationAlgorithm" ) ) )
++            {
++                sal_Int32 nID = 0;
++                if ( !( aAlgorithms[nInd].Value >>= nID )
++                  || ( nID != xml::crypto::DigestID::SHA256 && nID != xml::crypto::DigestID::SHA1 ) )
++                    throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!" ) ), uno::Reference< uno::XInterface >(), 2 );
++
++                m_nStartKeyGenerationID = nID;
++            }
++            else if ( aAlgorithms[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionAlgorithm" ) ) )
++            {
++                sal_Int32 nID = 0;
++                if ( !( aAlgorithms[nInd].Value >>= nID )
++                  || ( nID != xml::crypto::CipherID::AES_CBC_W3C_PADDING && nID != xml::crypto::CipherID::BLOWFISH_CFB_8 ) )
++                    throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!" ) ), uno::Reference< uno::XInterface >(), 2 );
++
++                m_nCommonEncryptionID = nID;
++            }
++            else if ( aAlgorithms[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ChecksumAlgorithm" ) ) )
++            {
++                sal_Int32 nID = 0;
++                if ( !( aAlgorithms[nInd].Value >>= nID )
++                  || ( nID != xml::crypto::DigestID::SHA1_1K && nID != xml::crypto::DigestID::SHA256_1K ) )
++                    throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!" ) ), uno::Reference< uno::XInterface >(), 2 );
++
++                m_nChecksumDigestID = nID;
++            }
++            else
++            {
++                OSL_ENSURE( sal_False, "Unexpected encryption algorithm is provided!" );
++                throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "unexpected algorithms list is provided." ) ), uno::Reference< uno::XInterface >(), 2 );
++            }
++        }
+     }
+     else
+         throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+@@ -1665,32 +1808,41 @@ Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName )
+     //	throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+     Any aAny;
+-    if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "EncryptionKey" ) ) )
++    if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( ENCRYPTION_KEY_PROPERTY ) ) )
+     {
+         aAny <<= m_aEncryptionKey;
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasEncryptedEntries" ) ) )
++    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) )
+     {
+-        aAny <<= m_bHasEncryptedEntries;
++        ::comphelper::SequenceAsHashMap aAlgorithms;
++        aAlgorithms[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StartKeyGenerationAlgorithm" ) ) ] <<= m_nStartKeyGenerationID;
++        aAlgorithms[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionAlgorithm" ) ) ] <<= m_nCommonEncryptionID;
++        aAlgorithms[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChecksumAlgorithm" ) ) ] <<= m_nChecksumDigestID;
++        aAny <<= aAlgorithms.getAsConstNamedValueList();
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasNonEncryptedEntries" ) ) )
++    if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
+     {
+-        aAny <<= m_bHasNonEncryptedEntries;
++        aAny <<= m_aStorageEncryptionKeys;
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "IsInconsistent" ) ) )
++    else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( HAS_ENCRYPTED_ENTRIES_PROPERTY ) ) )
+     {
+-        aAny <<= m_bInconsistent;
++        aAny <<= m_bHasEncryptedEntries;
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "UseManifest" ) ) )
++    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( HAS_NONENCRYPTED_ENTRIES_PROPERTY ) ) )
+     {
+-        aAny <<= m_bUseManifest;
++        aAny <<= m_bHasNonEncryptedEntries;
++        return aAny;
++    }
++    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( IS_INCONSISTENT_PROPERTY ) ) )
++    {
++        aAny <<= m_bInconsistent;
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "MediaTypeFallbackUsed" ) ) )
++    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( MEDIATYPE_FALLBACK_USED_PROPERTY ) ) )
+     {
+         aAny <<= m_bMediaTypeFallbackUsed;
+         return aAny;
+diff --git a/package/source/zippackage/ZipPackageEntry.hxx b/package/source/zippackage/ZipPackageEntry.hxx
+deleted file mode 100644
+index eef9dd9..0000000
+--- a/package/source/zippackage/ZipPackageEntry.hxx
++++ /dev/null
+@@ -1,106 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-#ifndef _ZIP_PACKAGE_ENTRY_HXX
+-#define _ZIP_PACKAGE_ENTRY_HXX
+-
+-#include <com/sun/star/container/XChild.hpp>
+-#include <com/sun/star/container/XNamed.hpp>
+-#include <com/sun/star/beans/XPropertySet.hpp>
+-#include <com/sun/star/lang/XUnoTunnel.hpp>
+-#include <com/sun/star/container/XNameContainer.hpp>
+-#include <com/sun/star/lang/XServiceInfo.hpp>
+-#include <ZipEntry.hxx>
+-#include <cppuhelper/implbase5.hxx>
+-
+-class ZipPackageFolder;
+-
+-class ZipPackageEntry : public cppu::WeakImplHelper5 
+-<
+-    com::sun::star::container::XNamed,
+-    com::sun::star::container::XChild,
+-    com::sun::star::lang::XUnoTunnel,
+-    com::sun::star::beans::XPropertySet,
+-    com::sun::star::lang::XServiceInfo
+->
+-{
+-protected:
+-    ::rtl::OUString msName;
+-    bool mbIsFolder:1;
+-    bool mbAllowRemoveOnInsert:1;
+-    // com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > xParent;
+-    ::rtl::OUString		sMediaType;
+-    ZipPackageFolder * pParent;
+-public:
+-    ZipEntry aEntry;
+-    ZipPackageEntry ( bool bNewFolder = sal_False );
+-    virtual ~ZipPackageEntry( void );
+-
+-    ::rtl::OUString & GetMediaType () { return sMediaType; }
+-    void SetMediaType ( const ::rtl::OUString & sNewType) { sMediaType = sNewType; }
+-    void doSetParent ( ZipPackageFolder * pNewParent, sal_Bool bInsert );
+-    bool IsFolder ( ) { return mbIsFolder; }
+-    ZipPackageFolder* GetParent ( ) { return pParent; }
+-    void SetFolder ( bool bSetFolder ) { mbIsFolder = bSetFolder; }
+-
+-    void clearParent ( void )
+-    {
+-        // xParent.clear();
+-        pParent = NULL;
+-    }
+-    // XNamed
+-    virtual ::rtl::OUString SAL_CALL getName(  ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL setName( const ::rtl::OUString& aName ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-    // XChild
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent(  ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) 
+-        throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
+-    // XUnoTunnel
+-    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) 
+-        throw(::com::sun::star::uno::RuntimeException) = 0;
+-    // XPropertySet
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+-    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) = 0;
+-    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-};
+-#endif
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
+index c412af1..534488d 100644
+--- a/package/source/zippackage/ZipPackageFolder.cxx
++++ b/package/source/zippackage/ZipPackageFolder.cxx
+@@ -305,7 +305,7 @@ static void ImplSetStoredData( ZipEntry & rEntry, Reference < XInputStream> & rS
+     rEntry.nCrc = aCRC32.getValue();
+ }
+ 
+-bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo &rInfo, OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool &rRandomPool)
++bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo &rInfo, OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool)
+ {
+     bool bSuccess = true;
+ 
+@@ -317,6 +317,10 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+     const OUString sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) );
+     const OUString sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) );
+     const OUString sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) );
++    const ::rtl::OUString sEncryptionAlgProperty    ( RTL_CONSTASCII_USTRINGPARAM ( "EncryptionAlgorithm" ) );
++    const ::rtl::OUString sStartKeyAlgProperty  ( RTL_CONSTASCII_USTRINGPARAM ( "StartKeyAlgorithm" ) );
++    const ::rtl::OUString sDigestAlgProperty    ( RTL_CONSTASCII_USTRINGPARAM ( "DigestAlgorithm" ) );
++    const ::rtl::OUString  sDerivedKeySizeProperty  ( RTL_CONSTASCII_USTRINGPARAM ( "DerivedKeySize" ) );
+ 
+     Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
+ 
+@@ -450,7 +454,6 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+                     }
+                     else
+                     {
+-                        OSL_FAIL( "The package component requires that every stream either be FROM a package or it must support XSeekable!" );
+                         bSuccess = false;
+                         return bSuccess;
+                     }
+@@ -458,7 +461,6 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+             }
+             catch ( Exception& )
+             {
+-                OSL_FAIL( "The stream provided to the package component has problems!" );
+                 bSuccess = false;
+                 return bSuccess;
+             }
+@@ -467,9 +469,9 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+             {
+                 if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
+                 {
+-                    Sequence < sal_uInt8 > aSalt ( 16 ), aVector ( 8 );
++                    Sequence < sal_Int8 > aSalt ( 16 ), aVector ( rInfo.pStream->GetBlockSize() );
+                     rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
+-                    rtl_random_getBytes ( rRandomPool, aVector.getArray(), 8 );
++                    rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() );
+                     sal_Int32 nIterationCount = 1024;
+ 
+                     if ( !rInfo.pStream->HasOwnKey() )
+@@ -498,8 +500,20 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+ 
+                 if ( bRawStream || bTransportOwnEncrStreamAsRaw )
+                 {
++                    ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
++                    if ( !xEncData.is() )
++                        throw uno::RuntimeException();
++
+                     aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
+                     aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
++                    aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
++                    aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
++                    aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
++                    aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
++                    aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
++                    aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
++                    aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
++                    aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
+                 }
+             }
+         }
+@@ -520,7 +534,6 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+                 if ( !xStream.is() )
+                 {
+                     // Make sure that we actually _got_ a new one !
+-                    OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
+                     bSuccess = false;
+                     return bSuccess;
+                 }
+@@ -531,7 +544,7 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+                 if ( bRawStream )
+                     xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() );
+ 
+-                rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream->getEncryptionData(), sal_False );
++                rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, sal_False );
+                 // the entry is provided to the ZipOutputStream that will delete it
+                 pAutoTempEntry.release();
+ 
+@@ -549,12 +562,10 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+             }
+             catch ( ZipException& )
+             {
+-                OSL_FAIL( "Error writing ZipOutputStream" );
+                 bSuccess = false;
+             }
+             catch ( IOException& )
+             {
+-                OSL_FAIL( "Error writing ZipOutputStream" );
+                 bSuccess = false;
+             }
+         }
+@@ -576,7 +587,6 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+                 if ( !xStream.is() )
+                 {
+                     // Make sure that we actually _got_ a new one !
+-                    OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
+                     bSuccess = false;
+                     return bSuccess;
+                 }
+@@ -590,7 +600,7 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+ 
+             try
+             {
+-                rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream->getEncryptionData(), bToBeEncrypted);
++                rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted);
+                 // the entry is provided to the ZipOutputStream that will delete it
+                 pAutoTempEntry.release();
+ 
+@@ -607,19 +617,30 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+             }
+             catch ( ZipException& )
+             {
+-                OSL_FAIL( "Error writing ZipOutputStream" );
+                 bSuccess = false;
+             }
+             catch ( IOException& )
+             {
+-                OSL_FAIL( "Error writing ZipOutputStream" );
+                 bSuccess = false;
+             }
+ 
+             if ( bToBeEncrypted )
+             {
++                ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
++                if ( !xEncData.is() )
++                    throw uno::RuntimeException();
++
+                 aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
+                 aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
++                aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
++                aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
++                aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
++                aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
++                aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
++                aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
++                aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
++                aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
++
+                 rInfo.pStream->SetIsEncrypted ( sal_True );
+             }
+         }
+@@ -665,7 +686,7 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
+     return bSuccess;
+ }
+ 
+-void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool &rRandomPool)
++void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool )
+     throw(RuntimeException)
+ {
+     bool bWritingFailed = false;
+@@ -681,18 +702,15 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
+ 
+         try
+         {
+-            rtl::Reference < EncryptionData > aEmptyEncr;
+-            rZipOut.putNextEntry ( *pTempEntry, aEmptyEncr, sal_False );
++            rZipOut.putNextEntry ( *pTempEntry, NULL, sal_False );
+             rZipOut.rawCloseEntry();
+         }
+         catch ( ZipException& )
+         {
+-            OSL_FAIL( "Error writing ZipOutputStream" );
+             bWritingFailed = true;
+         }
+         catch ( IOException& )
+         {
+-            OSL_FAIL( "Error writing ZipOutputStream" );
+             bWritingFailed = true;
+         }
+     }
+diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
+index ce72beb..424053c 100644
+--- a/package/source/zippackage/ZipPackageStream.cxx
++++ b/package/source/zippackage/ZipPackageStream.cxx
+@@ -35,6 +35,8 @@
+ #include <com/sun/star/io/XOutputStream.hpp>
+ #include <com/sun/star/io/XStream.hpp>
+ #include <com/sun/star/io/XSeekable.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
+ 
+ 
+ #include <ZipPackageStream.hxx>
+@@ -75,13 +77,17 @@ ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
+ , bToBeEncrypted ( sal_False )
+ , bHaveOwnKey ( sal_False )
+ , bIsEncrypted ( sal_False )
+-, xEncryptionData ( )
++, m_nImportedStartKeyAlgorithm( 0 )
++, m_nImportedEncryptionAlgorithm( 0 )
++, m_nImportedChecksumAlgorithm( 0 )
++, m_nImportedDerivedKeySize( 0 )
+ , m_nStreamMode( PACKAGE_STREAM_NOTSET )
+ , m_nMagicalHackPos( 0 )
+ , m_nMagicalHackSize( 0 )
+ , m_bHasSeekable( sal_False )
+ , m_bCompressedIsSetFromOutside( sal_False )
+ , m_bFromManifest( sal_False )
++, m_bUseWinEncoding( false )
+ {
+     OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" );
+ 
+@@ -138,7 +144,7 @@ void ZipPackageStream::CloseOwnStreamIfAny()
+ }
+ 
+ //--------------------------------------------------------------------------
+-uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream()
++uno::Reference< io::XInputStream > ZipPackageStream::GetOwnSeekStream()
+ {
+     if ( !m_bHasSeekable && xStream.is() )
+     {
+@@ -164,7 +170,7 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
+     if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() )
+         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+-    if ( !xEncryptionData.is() )
++    if ( m_xBaseEncryptionData.is() )
+         throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ),
+                             Reference< XInterface >() );
+ 
+@@ -174,8 +180,8 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
+                             Reference< XInterface >() );
+ 
+     // skip header
+-    xSeek->seek( n_ConstHeaderSize + xEncryptionData->aInitVector.getLength() +
+-                    xEncryptionData->aSalt.getLength() + xEncryptionData->aDigest.getLength() );
++    xSeek->seek( n_ConstHeaderSize + getInitialisationVector().getLength() +
++                    getSalt().getLength() + getDigest().getLength() );
+ 
+     // create temporary stream
+     uno::Reference < io::XOutputStream > xTempOut(
+@@ -195,6 +201,85 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
+ }
+ 
+ //--------------------------------------------------------------------------
++sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const
++{
++    return m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID();
++}
++
++//--------------------------------------------------------------------------
++sal_Int32 ZipPackageStream::GetBlockSize() const
++{
++    return GetEncryptionAlgorithm() == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
++}
++
++//--------------------------------------------------------------------------
++::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding )
++{
++    ::rtl::Reference< EncryptionData > xResult;
++    if ( m_xBaseEncryptionData.is() )
++        xResult = new EncryptionData(
++            *m_xBaseEncryptionData,
++            GetEncryptionKey( bUseWinEncoding ),
++            GetEncryptionAlgorithm(),
++            m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(),
++            m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize(),
++            GetStartKeyGenID() );
++
++    return xResult;
++}
++
++//--------------------------------------------------------------------------
++void ZipPackageStream::SetBaseEncryptionData( const ::rtl::Reference< BaseEncryptionData >& xData )
++{
++    m_xBaseEncryptionData = xData;
++}
++
++//--------------------------------------------------------------------------
++uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding )
++{
++    uno::Sequence< sal_Int8 > aResult;
++    sal_Int32 nKeyGenID = GetStartKeyGenID();
++    bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding );
++
++    if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() )
++    {
++        ::rtl::OUString aNameToFind;
++        if ( nKeyGenID == xml::crypto::DigestID::SHA256 )
++            aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
++        else if ( nKeyGenID == xml::crypto::DigestID::SHA1 )
++        {
++            aNameToFind = bUseWinEncoding ? PACKAGE_ENCRYPTIONDATA_SHA1MS1252 : PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
++        }
++        else
++            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );
++
++        for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
++            if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) )
++                m_aStorageEncryptionKeys[nInd].Value >>= aResult;
++
++        // empty keys are not allowed here
++        // so it is not important whether there is no key, or the key is empty, it is an error
++        if ( !aResult.getLength() )
++            throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() );
++    }
++    else
++        aResult = m_aEncryptionKey;
++
++    if ( !aResult.getLength() || !bHaveOwnKey )
++        aResult = rZipPackage.GetEncryptionKey();
++
++    return aResult;
++}
++
++//--------------------------------------------------------------------------
++sal_Int32 ZipPackageStream::GetStartKeyGenID()
++{
++    // generally should all the streams use the same Start Key
++    // but if raw copy without password takes place, we should preserve the imported algorithm
++    return m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetStartKeyGenID();
++}
++
++//--------------------------------------------------------------------------
+ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr )
+ {
+     if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || (bAddHeaderForEncr && !bToBeEncrypted) )
+@@ -204,8 +289,7 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B
+ 
+     if ( bToBeEncrypted )
+     {
+-        aKey = ( !xEncryptionData.is() || !bHaveOwnKey ) ? rZipPackage.getEncryptionKey() :
+-                                                                                xEncryptionData->aKey;
++        aKey = GetEncryptionKey();
+         if ( !aKey.getLength() )
+             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+     }
+@@ -246,7 +330,7 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B
+         xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( bToBeCompressed ) );
+         if ( bToBeEncrypted )
+         {
+-            xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ), makeAny( aKey ) );
++            xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ), makeAny( aKey ) );
+             xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) );
+         }
+ 
+@@ -317,7 +401,7 @@ sal_Bool ZipPackageStream::ParsePackageRawStream()
+ 
+     sal_Bool bOk = sal_False;
+ 
+-    rtl::Reference < EncryptionData > xTempEncrData;
++    rtl::Reference < BaseEncryptionData > xTempEncrData;
+     sal_Int32 nMagHackSize = 0;
+     Sequence < sal_Int8 > aHeader ( 4 );
+ 
+@@ -333,17 +417,25 @@ sal_Bool ZipPackageStream::ParsePackageRawStream()
+             if ( nHeader == n_ConstHeader )
+             {
+                 // this is one of our god-awful, but extremely devious hacks, everyone cheer
+-                xTempEncrData = new EncryptionData;
++                xTempEncrData = new BaseEncryptionData;
+ 
+                 ::rtl::OUString aMediaType;
+-                if ( ZipFile::StaticFillData ( xTempEncrData, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
++                sal_Int32 nEncAlgorithm = 0;
++                sal_Int32 nChecksumAlgorithm = 0;
++                sal_Int32 nDerivedKeySize = 0;
++                sal_Int32 nStartKeyGenID = 0;
++                if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
+                 {
+                     // We'll want to skip the data we've just read, so calculate how much we just read
+                     // and remember it
+-                    m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->aSalt.getLength()
+-                                                        + xTempEncrData->aInitVector.getLength()
+-                                                        + xTempEncrData->aDigest.getLength()
++                    m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->m_aSalt.getLength()
++                                                        + xTempEncrData->m_aInitVector.getLength()
++                                                        + xTempEncrData->m_aDigest.getLength()
+                                                         + aMediaType.getLength() * sizeof( sal_Unicode );
++                    m_nImportedEncryptionAlgorithm = nEncAlgorithm;
++                    m_nImportedChecksumAlgorithm = nChecksumAlgorithm;
++                    m_nImportedDerivedKeySize = nDerivedKeySize;
++                    m_nImportedStartKeyAlgorithm = nStartKeyGenID;
+                     m_nMagicalHackSize = nMagHackSize;
+                     sMediaType = aMediaType;
+ 
+@@ -362,7 +454,7 @@ sal_Bool ZipPackageStream::ParsePackageRawStream()
+         return sal_False;
+     }
+ 
+-    xEncryptionData = xTempEncrData;
++    m_xBaseEncryptionData = xTempEncrData;
+     SetIsEncrypted ( sal_True );
+     // it's already compressed and encrypted
+     bToBeEncrypted = bToBeCompressed = sal_False;
+@@ -385,10 +477,11 @@ void ZipPackageStream::SetPackageMember( sal_Bool bNewValue )
+ // XActiveDataSink
+ //--------------------------------------------------------------------------
+ void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStream >& aStream )
+-        throw(RuntimeException)
++        throw( RuntimeException )
+ {
+     // if seekable access is required the wrapping will be done on demand
+     xStream = aStream;
++    m_nImportedEncryptionAlgorithm = 0;
+     m_bHasSeekable = sal_False;
+     SetPackageMember ( sal_False );
+     aEntry.nTime = -1;
+@@ -397,15 +490,13 @@ void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStrea
+ 
+ //--------------------------------------------------------------------------
+ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData()
+-        throw(RuntimeException)
++        throw( RuntimeException )
+ {
+     try
+     {
+         if (IsPackageMember())
+         {
+-            if ( xEncryptionData.is() && !bHaveOwnKey )
+-                xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+-            return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++            return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+         }
+         else if ( GetOwnSeekStream().is() )
+         {
+@@ -434,9 +525,7 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream(  )
+     {
+         if (IsPackageMember())
+         {
+-            if ( xEncryptionData.is() && !bHaveOwnKey )
+-                xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+-            return rZipPackage.getZipFile().getInputStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++            return rZipPackage.getZipFile().getInputStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+         }
+         else if ( GetOwnSeekStream().is() )
+         {
+@@ -459,7 +548,7 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream(  )
+ 
+ // XDataSinkEncrSupport
+ //--------------------------------------------------------------------------
+-Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
++uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
+         throw ( packages::WrongPasswordException,
+                 io::IOException,
+                 RuntimeException )
+@@ -472,18 +561,28 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
+     if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
+         throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+-    if ( xEncryptionData.is() && !bHaveOwnKey )
+-        xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+-
+     if (IsPackageMember())
+     {
+-        if ( xEncryptionData.is() && !bHaveOwnKey )
+-            xEncryptionData->aKey = rZipPackage.getEncryptionKey();
+-
+-        return rZipPackage.getZipFile().getDataStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++        uno::Reference< io::XInputStream > xResult;
++        try
++        {
++            xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++        }
++        catch( packages::WrongPasswordException& )
++        {
++            // workaround for the encrypted documents generated with the old OOo1.x bug.
++            if ( rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 && !m_bUseWinEncoding )
++            {
++                xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++                m_bUseWinEncoding = true;
++            }
++            else
++                throw;
++        }
++        return xResult;
+     }
+     else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
+-        return ZipFile::StaticGetDataFromRawStream( GetOwnSeekStream(), xEncryptionData );
++        return ZipFile::StaticGetDataFromRawStream( m_xFactory, GetOwnSeekStream(), GetEncryptionData() );
+     else if ( GetOwnSeekStream().is() )
+     {
+         return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
+@@ -508,10 +607,10 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
+ 
+     if (IsPackageMember())
+     {
+-        if ( !bIsEncrypted || !xEncryptionData.is() )
++        if ( !bIsEncrypted || !GetEncryptionData().is() )
+             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+-        return rZipPackage.getZipFile().getWrappedRawStream( aEntry, xEncryptionData, sMediaType, rZipPackage.GetSharedMutexRef() );
++        return rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), sMediaType, rZipPackage.GetSharedMutexRef() );
+     }
+     else if ( GetOwnSeekStream().is() )
+     {
+@@ -528,7 +627,7 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
+ 
+ 
+ //--------------------------------------------------------------------------
+-void SAL_CALL ZipPackageStream::setDataStream( const Reference< io::XInputStream >& aStream )
++void SAL_CALL ZipPackageStream::setDataStream( const uno::Reference< io::XInputStream >& aStream )
+         throw ( io::IOException,
+                 RuntimeException )
+ {
+@@ -541,7 +640,7 @@ void SAL_CALL ZipPackageStream::setRawStream( const Reference< io::XInputStream
+         throw ( packages::EncryptionNotAllowedException,
+                 packages::NoRawFormatException,
+                 io::IOException,
+-                RuntimeException)
++                RuntimeException )
+ {
+     // wrap the stream in case it is not seekable
+     Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory );
+@@ -582,7 +681,7 @@ uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream(
+ 
+     if (IsPackageMember())
+     {
+-        return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() );
++        return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
+     }
+     else if ( GetOwnSeekStream().is() )
+     {
+@@ -660,8 +759,8 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName,
+                                                 2 );
+ 
+             bToBeEncrypted = bEnc;
+-            if ( bToBeEncrypted && !xEncryptionData.is())
+-                xEncryptionData = new EncryptionData;
++            if ( bToBeEncrypted && !m_xBaseEncryptionData.is())
++                m_xBaseEncryptionData = new BaseEncryptionData;
+         }
+         else
+             throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ),
+@@ -669,7 +768,7 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName,
+                                             2 );
+ 
+     }
+-    else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) )
++    else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) )
+     {
+         if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
+             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+@@ -685,8 +784,8 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName,
+                 Sequence < sal_Int8 > aSequence ( nPathLength );
+                 sal_Int8 *pArray = aSequence.getArray();
+                 const sal_Unicode *pChar = sTempString.getStr();
+-                for ( sal_Int16 i = 0; i < nPathLength; i++)
+-                    pArray[i] = static_cast < const sal_Int8 > (pChar[i]);
++                for ( sal_Int16 i = 0; i < nPathLength; i++ )
++                    pArray[i] = static_cast < const sal_Int8 > ( pChar[i] );
+                 aNewKey = aSequence;
+             }
+             else
+@@ -697,19 +796,57 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName,
+ 
+         if ( aNewKey.getLength() )
+         {
+-            if ( !xEncryptionData.is())
+-                xEncryptionData = new EncryptionData;
++            if ( !m_xBaseEncryptionData.is() )
++                m_xBaseEncryptionData = new BaseEncryptionData;
+ 
+-            xEncryptionData->aKey = aNewKey;
++            m_aEncryptionKey = aNewKey;
+             // In case of new raw stream, the stream must not be encrypted on storing
+             bHaveOwnKey = sal_True;
+             if ( m_nStreamMode != PACKAGE_STREAM_RAW )
+                 bToBeEncrypted = sal_True;
+         }
+         else
++        {
+             bHaveOwnKey = sal_False;
++            m_aEncryptionKey.realloc( 0 );
+     }
+-    else if (aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
++
++        m_aStorageEncryptionKeys.realloc( 0 );
++    }
++    else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
++    {
++        if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
++            throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
++
++        uno::Sequence< beans::NamedValue > aKeys;
++        if ( !( aValue >>= aKeys ) )
++        {
++                throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for StorageEncryptionKeys property!\n" ) ),
++                                                uno::Reference< XInterface >(),
++                                                2 );
++        }
++
++        if ( aKeys.getLength() )
++        {
++            if ( !m_xBaseEncryptionData.is() )
++                m_xBaseEncryptionData = new BaseEncryptionData;
++
++            m_aStorageEncryptionKeys = aKeys;
++
++            // In case of new raw stream, the stream must not be encrypted on storing
++            bHaveOwnKey = sal_True;
++            if ( m_nStreamMode != PACKAGE_STREAM_RAW )
++                bToBeEncrypted = sal_True;
++        }
++        else
++        {
++            bHaveOwnKey = sal_False;
++            m_aStorageEncryptionKeys.realloc( 0 );
++        }
++
++        m_aEncryptionKey.realloc( 0 );
++    }
++    else if ( aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) )
+     {
+         sal_Bool bCompr = sal_False;
+ 
+@@ -763,9 +900,14 @@ Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
+         aAny <<= bToBeCompressed;
+         return aAny;
+     }
+-    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
++    else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) )
++    {
++        aAny <<= m_aEncryptionKey;
++        return aAny;
++    }
++    else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
+     {
+-        aAny <<= !xEncryptionData.is() ? Sequence < sal_Int8 > () : xEncryptionData->aKey;
++        aAny <<= m_aStorageEncryptionKeys;
+         return aAny;
+     }
+     else
+diff --git a/package/source/zippackage/ZipPackageStream.hxx b/package/source/zippackage/ZipPackageStream.hxx
+deleted file mode 100644
+index 321e385..0000000
+--- a/package/source/zippackage/ZipPackageStream.hxx
++++ /dev/null
+@@ -1,196 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*************************************************************************
+- *
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- * 
+- * Copyright 2000, 2010 Oracle and/or its affiliates.
+- *
+- * OpenOffice.org - a multi-platform office productivity suite
+- *
+- * This file is part of OpenOffice.org.
+- *
+- * OpenOffice.org is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU Lesser General Public License version 3
+- * only, as published by the Free Software Foundation.
+- *
+- * OpenOffice.org is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License version 3 for more details
+- * (a copy is included in the LICENSE file that accompanied this code).
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * version 3 along with OpenOffice.org.  If not, see
+- * <http://www.openoffice.org/license.html>
+- * for a copy of the LGPLv3 License.
+- *
+- ************************************************************************/
+-#ifndef _ZIP_PACKAGE_STREAM_HXX
+-#define _ZIP_PACKAGE_STREAM_HXX
+-
+-#include <com/sun/star/io/XActiveDataSink.hpp>
+-#include <com/sun/star/io/XSeekable.hpp>
+-#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
+-#include <ZipPackageEntry.hxx>
+-#include <rtl/ref.hxx>
+-#include <EncryptionData.hxx>
+-#include <cppuhelper/implbase2.hxx>
+-#include <mutexholder.hxx>
+-
+-#define PACKAGE_STREAM_NOTSET			0
+-#define PACKAGE_STREAM_PACKAGEMEMBER	1
+-#define PACKAGE_STREAM_DETECT			2
+-#define PACKAGE_STREAM_DATA				3
+-#define PACKAGE_STREAM_RAW				4
+-
+-class ZipPackage;
+-struct ZipEntry;
+-class ZipPackageStream : public cppu::ImplInheritanceHelper2
+-<
+-    ZipPackageEntry,
+-    ::com::sun::star::io::XActiveDataSink,
+-    ::com::sun::star::packages::XDataSinkEncrSupport
+->
+-{
+-protected:
+-    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
+-    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+-    ZipPackage 			&rZipPackage;
+-    sal_Bool			bToBeCompressed, bToBeEncrypted, bHaveOwnKey, bIsEncrypted;
+-    rtl::Reference < EncryptionData > xEncryptionData;
+-
+-    sal_uInt8	m_nStreamMode;
+-    sal_uInt32	m_nMagicalHackPos;
+-    sal_uInt32	m_nMagicalHackSize;
+-
+-    sal_Bool m_bHasSeekable;
+-
+-    sal_Bool m_bCompressedIsSetFromOutside;
+-
+-    sal_Bool m_bFromManifest;
+-
+-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& GetOwnSeekStream();
+-
+-public:
+-    sal_Bool HasOwnKey () const	 { return bHaveOwnKey;}
+-    sal_Bool IsToBeCompressed () const { return bToBeCompressed;}
+-    sal_Bool IsToBeEncrypted () const { return bToBeEncrypted;}
+-    sal_Bool IsEncrypted () const  	 { return bIsEncrypted;}
+-    sal_Bool IsPackageMember () const { return m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER;}
+-
+-    sal_Bool IsFromManifest() const { return m_bFromManifest; }
+-    void SetFromManifest( sal_Bool bValue ) { m_bFromManifest = bValue; }
+-
+-    rtl::Reference < EncryptionData > & getEncryptionData ()
+-    { return xEncryptionData;}
+-    const com::sun::star::uno::Sequence < sal_Int8 >& getKey () const
+-    { return xEncryptionData->aKey;}
+-    const com::sun::star::uno::Sequence < sal_uInt8 >& getInitialisationVector () const
+-    { return xEncryptionData->aInitVector;}
+-    const com::sun::star::uno::Sequence < sal_uInt8 >& getDigest () const
+-    { return xEncryptionData->aDigest;}
+-    const com::sun::star::uno::Sequence < sal_uInt8 >& getSalt () const
+-    { return xEncryptionData->aSalt;}
+-    sal_Int32 getIterationCount () const
+-    { return xEncryptionData->nIterationCount;}
+-    sal_Int32 getSize () const
+-    { return aEntry.nSize;}
+-
+-    sal_uInt8 GetStreamMode() const { return m_nStreamMode; }
+-    sal_uInt32 GetMagicalHackPos() const { return m_nMagicalHackPos; }
+-    sal_uInt32 GetMagicalHackSize() const { return m_nMagicalHackSize; }
+-
+-    void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
+-    void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
+-    void SetToBeEncrypted (sal_Bool bNewValue)  
+-    { 
+-        bToBeEncrypted  = bNewValue;
+-        if ( bToBeEncrypted && !xEncryptionData.is())
+-            xEncryptionData = new EncryptionData;
+-        else if ( !bToBeEncrypted && xEncryptionData.is() )
+-            xEncryptionData.clear();
+-    }
+-    void SetPackageMember (sal_Bool bNewValue);
+-    void setKey (const com::sun::star::uno::Sequence < sal_Int8 >& rNewKey )
+-    { xEncryptionData->aKey = rNewKey;}
+-    void setInitialisationVector (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewVector )
+-    { xEncryptionData->aInitVector = rNewVector;}
+-    void setSalt (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewSalt )
+-    { xEncryptionData->aSalt = rNewSalt;}
+-    void setDigest (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewDigest )
+-    { xEncryptionData->aDigest = rNewDigest;}
+-    void setIterationCount (const sal_Int32 nNewCount)
+-    { xEncryptionData->nIterationCount = nNewCount;}
+-    void setSize (const sal_Int32 nNewSize);
+-
+-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnStreamNoWrap() { return xStream; }
+-
+-    void CloseOwnStreamIfAny();
+-
+-    ZipPackageStream ( ZipPackage & rNewPackage,
+-                        const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
+-                        sal_Bool bAllowRemoveOnInsert );
+-    virtual ~ZipPackageStream( void );
+-
+-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawEncrStreamNoHeaderCopy();
+-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > TryToGetRawFromDataStream(
+-                                                                                    sal_Bool bAddHeaderForEncr );
+-
+-    sal_Bool ParsePackageRawStream();
+-
+-    void setZipEntryOnLoading( const ZipEntry &rInEntry);
+-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
+-        throw(::com::sun::star::uno::RuntimeException);
+-    
+-    static const ::com::sun::star::uno::Sequence < sal_Int8 >& static_getImplementationId();
+-
+-    // XActiveDataSink
+-    virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-
+-    // XDataSinkEncrSupport
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream()
+-        throw ( ::com::sun::star::packages::WrongPasswordException,
+-                ::com::sun::star::io::IOException,
+-                ::com::sun::star::uno::RuntimeException );
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream()
+-        throw ( ::com::sun::star::packages::NoEncryptionException,
+-                ::com::sun::star::io::IOException,
+-                ::com::sun::star::uno::RuntimeException );
+-    virtual void SAL_CALL setDataStream(
+-                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+-        throw ( ::com::sun::star::io::IOException,
+-                ::com::sun::star::uno::RuntimeException );
+-    virtual void SAL_CALL setRawStream(
+-                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
+-        throw ( ::com::sun::star::packages::EncryptionNotAllowedException,
+-                ::com::sun::star::packages::NoRawFormatException,
+-                ::com::sun::star::io::IOException,
+-                ::com::sun::star::uno::RuntimeException );
+-    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStream()
+-        throw ( ::com::sun::star::io::IOException,
+-                ::com::sun::star::uno::RuntimeException );
+-
+-    // XUnoTunnel
+-    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) 
+-        throw(::com::sun::star::uno::RuntimeException);
+-
+-    // XPropertySet
+-    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) 
+-        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+-
+-    // XServiceInfo
+-    virtual ::rtl::OUString SAL_CALL getImplementationName(  ) 
+-        throw (::com::sun::star::uno::RuntimeException);
+-    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) 
+-        throw (::com::sun::star::uno::RuntimeException);
+-    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) 
+-        throw (::com::sun::star::uno::RuntimeException);
+-};
+-#endif
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/package/source/zippackage/zipfileaccess.cxx b/package/source/zippackage/zipfileaccess.cxx
+index d0dc59f..60b148a 100644
+--- a/package/source/zippackage/zipfileaccess.cxx
++++ b/package/source/zippackage/zipfileaccess.cxx
+@@ -41,6 +41,7 @@
+ #include <EncryptionData.hxx>
+ 
+ #include <ucbhelper/content.hxx>
++#include <rtl/ref.hxx>
+ 
+ #include <memory>
+ 
+@@ -252,7 +253,7 @@ uno::Any SAL_CALL OZipFileAccess::getByName( const ::rtl::OUString& aName )
+         throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ 
+     uno::Reference< io::XInputStream > xEntryStream( m_pZipFile->getDataStream( (*aIter).second,
+-                                                                                new EncryptionData(),
++                                                                                ::rtl::Reference< EncryptionData >(),
+                                                                                 sal_False,
+                                                                                 m_aMutexHolder ) );
+ 
+@@ -367,7 +368,7 @@ uno::Reference< io::XInputStream > SAL_CALL OZipFileAccess::getStreamByPattern(
+         if ( StringGoodForPattern_Impl( (*aIter).second.sPath, aPattern ) )
+         {
+             uno::Reference< io::XInputStream > xEntryStream( m_pZipFile->getDataStream( (*aIter).second, 
+-                                                                                        new EncryptionData(), 
++                                                                                        ::rtl::Reference< EncryptionData >(),
+                                                                                         sal_False,
+                                                                                         m_aMutexHolder ) );
+ 
+diff --git a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
+index b90052a..4e0ad63 100644
+--- a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
++++ b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
+@@ -134,7 +134,7 @@ public:
+     ~DigitalSignaturesDialog();
+ 
+             // Initialize the dialog and the security environment, returns sal_True on success
+-    sal_Bool    Init( const rtl::OUString& rTokenName );
++    sal_Bool    Init();
+ 
+             // Set the storage which should be signed or verified
+     void    SetStorage( const cssu::Reference < css::embed::XStorage >& rxStore );
+diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+index 7401f23..eae0ce8 100644
+--- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
++++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+@@ -133,10 +133,9 @@ public:
+     XMLSignatureHelper(const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& mrCtx );
+     ~XMLSignatureHelper();
+ 
+-                // Initialize the security context with given crypto token.
+-                // Empty string means default crypto token.
++                // Initialize the security context with default crypto token.
+                 // Returns true for success.
+-    bool        Init( const rtl::OUString& rTokenPath );
++    bool        Init();
+ 
+                 // Set UriBinding to create input streams to open files.
+                 // Default implementation is capable to open files from disk.
+diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
+index 8032883..f53acb4 100644
+--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
++++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
+@@ -221,7 +221,7 @@ sal_Bool DocumentDigitalSignatures::ImplViewSignatures(
+     sal_Bool bChanges = sal_False;
+     DigitalSignaturesDialog aSignaturesDialog(
+         NULL, mxCtx, eMode, bReadOnly, m_sODFVersion, m_bHasDocumentSignature);
+-    bool bInit = aSignaturesDialog.Init( rtl::OUString() );
++    bool bInit = aSignaturesDialog.Init();
+     DBG_ASSERT( bInit, "Error initializing security context!" );
+     if ( bInit )
+     {
+@@ -277,7 +277,7 @@ DocumentDigitalSignatures::ImplVerifySignatures(
+ 
+     XMLSignatureHelper aSignatureHelper( mxCtx );
+ 
+-    bool bInit = aSignatureHelper.Init( rtl::OUString() );
++    bool bInit = aSignatureHelper.Init();
+ 
+     DBG_ASSERT( bInit, "Error initializing security context!" );
+ 
+@@ -380,7 +380,7 @@ void DocumentDigitalSignatures::manageTrustedSources(  ) throw (RuntimeException
+     Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
+ 
+     XMLSignatureHelper aSignatureHelper( mxCtx );
+-    if ( aSignatureHelper.Init( rtl::OUString() ) )
++    if ( aSignatureHelper.Init() )
+         xSecEnv = aSignatureHelper.GetSecurityEnvironment();
+ 
+     MacroSecurity aDlg( NULL, mxCtx, xSecEnv );
+@@ -392,7 +392,7 @@ void DocumentDigitalSignatures::showCertificate(
+ {
+     XMLSignatureHelper aSignatureHelper( mxCtx );
+ 
+-    bool bInit = aSignatureHelper.Init( rtl::OUString() );
++    bool bInit = aSignatureHelper.Init();
+ 
+     DBG_ASSERT( bInit, "Error initializing security context!" );
+ 
+diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+index 8a45f41..17ab79c 100644
+--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
++++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+@@ -259,9 +259,9 @@ DigitalSignaturesDialog::~DigitalSignaturesDialog()
+ {
+ }
+ 
+-sal_Bool DigitalSignaturesDialog::Init( const rtl::OUString& rTokenName )
++sal_Bool DigitalSignaturesDialog::Init()
+ {
+-    bool bInit = maSignatureHelper.Init( rTokenName );
++    bool bInit = maSignatureHelper.Init();
+ 
+     DBG_ASSERT( bInit, "Error initializing security context!" );
+ 
+diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+index 7673bd2..0959e11 100644
+--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
++++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+@@ -70,11 +70,9 @@ XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentCon
+ 
+ XMLSignatureHelper::~XMLSignatureHelper()
+ {
+-    if ( mxSEInitializer.is() && mxSecurityContext.is() )
+-        mxSEInitializer->freeSecurityContext( mxSecurityContext );
+ }
+ 
+-bool XMLSignatureHelper::Init( const rtl::OUString& rTokenPath )
++bool XMLSignatureHelper::Init()
+ {
+     DBG_ASSERT( !mxSEInitializer.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
+     DBG_ASSERT( !mxSecurityContext.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
+@@ -82,7 +80,7 @@ bool XMLSignatureHelper::Init( const rtl::OUString& rTokenPath )
+     ImplCreateSEInitializer();
+     
+     if ( mxSEInitializer.is() )
+-        mxSecurityContext = mxSEInitializer->createSecurityContext( rTokenPath );
++        mxSecurityContext = mxSEInitializer->createSecurityContext( ::rtl::OUString() );
+ 
+     return mxSecurityContext.is();
+ }
+diff --git a/xmlsecurity/source/xmlsec/makefile.mk b/xmlsecurity/source/xmlsec/makefile.mk
+index 44b668b..36b30f4 100644
+--- a/xmlsecurity/source/xmlsec/makefile.mk
++++ b/xmlsecurity/source/xmlsec/makefile.mk
+@@ -49,11 +49,11 @@ CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS)
+ .ENDIF
+ 
+ .IF "$(CRYPTO_ENGINE)" == "mscrypto"
+-CDEFS += -DXMLSEC_CRYPTO_MSCRYPTO -DXMLSEC_NO_XSLT
+-.ELSE
+-CDEFS += -DXMLSEC_CRYPTO_NSS -DXMLSEC_NO_XSLT
++CDEFS += -DXMLSEC_CRYPTO_MSCRYPTO
+ .ENDIF
+ 
++CDEFS += -DXMLSEC_NO_XSLT
++
+ # --- Files --------------------------------------------------------
+ SLOFILES = \
+     $(SLO)$/biginteger.obj \
+diff --git a/xmlsecurity/source/xmlsec/nss/ciphercontext.cxx b/xmlsecurity/source/xmlsec/nss/ciphercontext.cxx
+new file mode 100644
+index 0000000..93a17e3
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/ciphercontext.cxx
+@@ -0,0 +1,276 @@
++ /*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#include <precompiled_xmlsecurity.hxx>
++
++#include <osl/time.h>
++#include <rtl/random.h>
++#include <rtl/ref.hxx>
++
++#include "ciphercontext.hxx"
++
++using namespace ::com::sun::star;
++
++uno::Reference< xml::crypto::XCipherContext > OCipherContext::Create( CK_MECHANISM_TYPE nNSSCipherID, const uno::Sequence< ::sal_Int8 >& aKey, const uno::Sequence< ::sal_Int8 >& aInitializationVector, bool bEncryption, bool bW3CPadding )
++{
++    ::rtl::Reference< OCipherContext > xResult = new OCipherContext;
++
++    xResult->m_pSlot = PK11_GetBestSlot( nNSSCipherID, NULL );
++    if ( xResult->m_pSlot )
++    {
++        SECItem aKeyItem = { siBuffer, const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aKey.getConstArray() ) ), aKey.getLength() };
++        xResult->m_pSymKey = PK11_ImportSymKey( xResult->m_pSlot, nNSSCipherID, PK11_OriginDerive, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, &aKeyItem, NULL );
++        if ( xResult->m_pSymKey )
++        {
++            SECItem aIVItem = { siBuffer, const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aInitializationVector.getConstArray() ) ), aInitializationVector.getLength() };
++            xResult->m_pSecParam = PK11_ParamFromIV( nNSSCipherID, &aIVItem );
++            if ( xResult->m_pSecParam )
++            {
++                xResult->m_pContext = PK11_CreateContextBySymKey( nNSSCipherID, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, xResult->m_pSymKey, xResult->m_pSecParam);
++                if ( xResult->m_pContext )
++                {
++                    xResult->m_bEncryption = bEncryption;
++                    xResult->m_bW3CPadding = bW3CPadding;
++                    xResult->m_bPadding = bW3CPadding || ( PK11_GetPadMechanism( nNSSCipherID ) == nNSSCipherID );
++                    xResult->m_nBlockSize = PK11_GetBlockSize( nNSSCipherID, xResult->m_pSecParam );
++                    if ( xResult->m_nBlockSize <= SAL_MAX_INT8 )
++                        return xResult.get();
++                }
++            }
++        }
++    }
++
++    return uno::Reference< xml::crypto::XCipherContext >();
++}
++
++void OCipherContext::Dispose()
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++
++    if ( m_pContext )
++    {
++        PK11_DestroyContext( m_pContext, PR_TRUE );
++        m_pContext = NULL;
++    }
++
++    if ( m_pSecParam )
++    {
++        SECITEM_FreeItem( m_pSecParam, PR_TRUE );
++        m_pSecParam = NULL;
++    }
++
++    if ( m_pSymKey )
++    {
++        PK11_FreeSymKey( m_pSymKey );
++        m_pSymKey = NULL;
++    }
++
++    if ( m_pSlot )
++    {
++        PK11_FreeSlot( m_pSlot );
++        m_pSlot = NULL;
++    }
++
++    m_bDisposed = true;
++}
++
++uno::Sequence< ::sal_Int8 > SAL_CALL OCipherContext::convertWithCipherContext( const uno::Sequence< ::sal_Int8 >& aData )
++    throw ( lang::IllegalArgumentException, lang::DisposedException, uno::RuntimeException)
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++
++    if ( m_bBroken )
++        throw uno::RuntimeException();
++
++    if ( m_bDisposed )
++        throw lang::DisposedException();
++
++    uno::Sequence< sal_Int8 > aToConvert;
++    if ( aData.getLength() )
++    {
++        sal_Int32 nOldLastBlockLen = m_aLastBlock.getLength();
++        OSL_ENSURE( nOldLastBlockLen <= m_nBlockSize, "Unexpected last block size!" );
++
++        sal_Int32 nAvailableData = nOldLastBlockLen + aData.getLength();
++        sal_Int32 nToConvertLen = nAvailableData;
++        if ( m_bEncryption || !m_bW3CPadding )
++        {
++            if ( nAvailableData % m_nBlockSize == 0 )
++                nToConvertLen = nAvailableData;
++            else if ( nAvailableData < m_nBlockSize )
++                nToConvertLen = 0;
++            else
++                nToConvertLen = nAvailableData - nAvailableData % m_nBlockSize;
++        }
++        else
++        {
++            // decryption with W3C padding needs at least one block for finalizing
++            if ( nAvailableData < m_nBlockSize * 2 )
++                nToConvertLen = 0;
++            else
++                nToConvertLen = nAvailableData - nAvailableData % m_nBlockSize - m_nBlockSize;
++        }
++
++        aToConvert.realloc( nToConvertLen );
++        if ( nToConvertLen == 0 )
++        {
++            m_aLastBlock.realloc( nOldLastBlockLen + aData.getLength() );
++            rtl_copyMemory( m_aLastBlock.getArray() + nOldLastBlockLen, aData.getConstArray(), aData.getLength() );
++            // aToConvert stays empty
++        }
++        else if ( nToConvertLen < nOldLastBlockLen )
++        {
++            rtl_copyMemory( aToConvert.getArray(), m_aLastBlock.getConstArray(), nToConvertLen );
++            rtl_copyMemory( m_aLastBlock.getArray(), m_aLastBlock.getConstArray() + nToConvertLen, nOldLastBlockLen - nToConvertLen );
++            m_aLastBlock.realloc( nOldLastBlockLen - nToConvertLen + aData.getLength() );
++            rtl_copyMemory( m_aLastBlock.getArray() + nOldLastBlockLen - nToConvertLen, aData.getConstArray(), aData.getLength() );
++        }
++        else
++        {
++            rtl_copyMemory( aToConvert.getArray(), m_aLastBlock.getConstArray(), nOldLastBlockLen );
++            if ( nToConvertLen > nOldLastBlockLen )
++                rtl_copyMemory( aToConvert.getArray() + nOldLastBlockLen, aData.getConstArray(), nToConvertLen - nOldLastBlockLen );
++            m_aLastBlock.realloc( nAvailableData - nToConvertLen );
++            rtl_copyMemory( m_aLastBlock.getArray(), aData.getConstArray() + nToConvertLen - nOldLastBlockLen, nAvailableData - nToConvertLen );
++        }
++    }
++
++    uno::Sequence< sal_Int8 > aResult;
++    OSL_ENSURE( aToConvert.getLength() % m_nBlockSize == 0, "Unexpected size of the data to encrypt!" );
++    if ( aToConvert.getLength() )
++    {
++        int nResultLen = 0;
++        aResult.realloc( aToConvert.getLength() + m_nBlockSize );
++        if ( PK11_CipherOp( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() ), &nResultLen, aResult.getLength(), const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( aToConvert.getConstArray() ) ), aToConvert.getLength() ) != SECSuccess )
++        {
++            m_bBroken = true;
++            Dispose();
++            throw uno::RuntimeException();
++        }
++
++        m_nConverted += aToConvert.getLength();
++        aResult.realloc( nResultLen );
++    }
++
++    return aResult;
++}
++
++uno::Sequence< ::sal_Int8 > SAL_CALL OCipherContext::finalizeCipherContextAndDispose()
++    throw (lang::DisposedException, uno::RuntimeException)
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++
++    if ( m_bBroken )
++        throw uno::RuntimeException();
++
++    if ( m_bDisposed )
++        throw lang::DisposedException();
++
++    OSL_ENSURE( m_nBlockSize <= SAL_MAX_INT8, "Unexpected block size!" );
++    OSL_ENSURE( m_nConverted % m_nBlockSize == 0, "Unexpected amount of bytes is already converted!" );
++    sal_Int32 nSizeForPadding = ( m_nConverted + m_aLastBlock.getLength() ) % m_nBlockSize;
++
++    // if it is decryption, the amount of data should be rounded to the block size even in case of padding
++    if ( ( !m_bPadding || !m_bEncryption ) && nSizeForPadding )
++        throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The data should contain complete blocks only." ) ), uno::Reference< uno::XInterface >() );
++
++    if ( m_bW3CPadding && m_bEncryption )
++    {
++        // in this case the last block should be smaller than standtard block
++        // it will be increased with the padding
++        OSL_ENSURE( m_aLastBlock.getLength() < m_nBlockSize, "Unexpected size of cashed incomplete last block!" );
++
++        // W3CPadding handling for encryption
++        sal_Int32 nPaddingSize = m_nBlockSize - nSizeForPadding;
++        sal_Int32 nOldLastBlockLen = m_aLastBlock.getLength();
++        m_aLastBlock.realloc( nOldLastBlockLen + nPaddingSize );
++
++        if ( nPaddingSize > 1 )
++        {
++            TimeValue aTime;
++            osl_getSystemTime( &aTime );
++            rtlRandomPool aRandomPool = rtl_random_createPool();
++            rtl_random_addBytes( aRandomPool, &aTime, 8 );
++            rtl_random_getBytes( aRandomPool, m_aLastBlock.getArray() + nOldLastBlockLen, nPaddingSize - 1 );
++            rtl_random_destroyPool ( aRandomPool );
++        }
++        m_aLastBlock[m_aLastBlock.getLength() - 1] = static_cast< sal_Int8 >( nPaddingSize );
++    }
++
++    // finally should the last block be smaller than two standard blocks
++    OSL_ENSURE( m_aLastBlock.getLength() < m_nBlockSize * 2 , "Unexpected size of cashed incomplete last block!" );
++
++    uno::Sequence< sal_Int8 > aResult;
++    if ( m_aLastBlock.getLength() )
++    {
++        int nPrefResLen = 0;
++        aResult.realloc( m_aLastBlock.getLength() + m_nBlockSize );
++        if ( PK11_CipherOp( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() ), &nPrefResLen, aResult.getLength(), const_cast< unsigned char* >( reinterpret_cast< const unsigned char* >( m_aLastBlock.getConstArray() ) ), m_aLastBlock.getLength() ) != SECSuccess )
++        {
++            m_bBroken = true;
++            Dispose();
++            throw uno::RuntimeException();
++        }
++
++        aResult.realloc( nPrefResLen );
++        m_aLastBlock.realloc( 0 );
++    }
++
++    sal_Int32 nPrefixLen = aResult.getLength();
++    aResult.realloc( nPrefixLen + m_nBlockSize * 2 );
++    unsigned nFinalLen = 0;
++    if ( PK11_DigestFinal( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() + nPrefixLen ), &nFinalLen, aResult.getLength() - nPrefixLen ) != SECSuccess )
++    {
++        m_bBroken = true;
++        Dispose();
++        throw uno::RuntimeException();
++    }
++
++    aResult.realloc( nPrefixLen + nFinalLen );
++
++    if ( m_bW3CPadding && !m_bEncryption )
++    {
++        // W3CPadding handling for decryption
++        // aResult should have anough data, since we let m_aLastBlock be big enough in case of decryption
++        OSL_ENSURE( aResult.getLength() >= m_nBlockSize, "Not enough data to handle the padding!" );
++
++        sal_Int8 nBytesToRemove = aResult[aResult.getLength() - 1];
++        if ( nBytesToRemove <= 0 || nBytesToRemove > aResult.getLength() )
++        {
++            m_bBroken = true;
++            Dispose();
++            throw uno::RuntimeException();
++        }
++
++        aResult.realloc( aResult.getLength() - nBytesToRemove );
++    }
++
++    Dispose();
++
++    return aResult;
++}
++
+diff --git a/xmlsecurity/source/xmlsec/nss/ciphercontext.hxx b/xmlsecurity/source/xmlsec/nss/ciphercontext.hxx
+new file mode 100644
+index 0000000..1574a62
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/ciphercontext.hxx
+@@ -0,0 +1,89 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef _CIPHERCONTEXT_HXX
++#define _CIPHERCONTEXT_HXX
++
++#include <com/sun/star/xml/crypto/XCipherContext.hpp>
++
++#include <cppuhelper/implbase1.hxx>
++#include <osl/mutex.hxx>
++#include <pk11pub.h>
++
++class OCipherContext : public cppu::WeakImplHelper1< ::com::sun::star::xml::crypto::XCipherContext >
++{
++private:
++    ::osl::Mutex m_aMutex;
++
++    PK11SlotInfo* m_pSlot;
++    PK11SymKey* m_pSymKey;
++    SECItem* m_pSecParam;
++    PK11Context* m_pContext;
++
++    sal_Int32 m_nBlockSize;
++    ::com::sun::star::uno::Sequence< sal_Int8 > m_aLastBlock;
++
++    bool m_bEncryption;
++    bool m_bPadding;
++    bool m_bW3CPadding;
++    sal_Int64 m_nConverted;
++
++    bool m_bDisposed;
++    bool m_bBroken;
++
++    void Dispose();
++
++    OCipherContext()
++    : m_pSlot( NULL )
++    , m_pSymKey( NULL )
++    , m_pSecParam( NULL )
++    , m_pContext( NULL )
++    , m_nBlockSize( 0 )
++    , m_bEncryption( false )
++    , m_bPadding( false )
++    , m_bW3CPadding( false )
++    , m_nConverted( 0 )
++    , m_bDisposed( false )
++    , m_bBroken( false )
++    {}
++
++public:
++
++    virtual ~OCipherContext()
++    {
++        Dispose();
++    }
++
++    static ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > Create( CK_MECHANISM_TYPE nNSSCipherID, const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aKey, const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aInitializationVector, bool bEncryption, bool bW3CPadding );
++
++    // XCipherContext
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL convertWithCipherContext( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL finalizeCipherContextAndDispose(  ) throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++};
++
++#endif
++
+diff --git a/xmlsecurity/source/xmlsec/nss/digestcontext.cxx b/xmlsecurity/source/xmlsec/nss/digestcontext.cxx
+new file mode 100644
+index 0000000..4b3a0d0
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/digestcontext.cxx
+@@ -0,0 +1,101 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#include <precompiled_xmlsecurity.hxx>
++
++#include <pk11pub.h>
++#include "digestcontext.hxx"
++
++using namespace ::com::sun::star;
++
++ODigestContext::~ODigestContext()
++{
++    if ( m_pContext )
++    {
++        PK11_DestroyContext( m_pContext, PR_TRUE );
++        m_pContext = NULL;
++    }
++}
++
++void SAL_CALL ODigestContext::updateDigest( const uno::Sequence< ::sal_Int8 >& aData )
++    throw (lang::DisposedException, uno::RuntimeException)
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++
++    if ( m_bBroken )
++        throw uno::RuntimeException();
++
++    if ( m_bDisposed )
++        throw lang::DisposedException();
++
++    if ( !m_b1KData || m_nDigested < 1024 )
++    {
++        uno::Sequence< sal_Int8 > aToDigest = aData;
++        if ( m_b1KData && m_nDigested + aData.getLength() > 1024 )
++            aToDigest.realloc( 1024 - m_nDigested );
++
++        if ( PK11_DigestOp( m_pContext, reinterpret_cast< const unsigned char* >( aToDigest.getConstArray() ), aToDigest.getLength() ) != SECSuccess )
++        {
++            PK11_DestroyContext( m_pContext, PR_TRUE );
++            m_pContext = NULL;
++            m_bBroken = true;
++            throw uno::RuntimeException();
++        }
++
++        m_nDigested += aToDigest.getLength();
++    }
++}
++
++uno::Sequence< ::sal_Int8 > SAL_CALL ODigestContext::finalizeDigestAndDispose()
++    throw (lang::DisposedException, uno::RuntimeException)
++{
++    ::osl::MutexGuard aGuard( m_aMutex );
++
++    if ( m_bBroken )
++        throw uno::RuntimeException();
++
++    if ( m_bDisposed )
++        throw lang::DisposedException();
++
++    uno::Sequence< sal_Int8 > aResult( m_nDigestLength );
++    unsigned int nResultLen = 0;
++    if ( PK11_DigestFinal( m_pContext, reinterpret_cast< unsigned char* >( aResult.getArray() ), &nResultLen, aResult.getLength() ) != SECSuccess )
++    {
++        PK11_DestroyContext( m_pContext, PR_TRUE );
++        m_pContext = NULL;
++        m_bBroken = true;
++        throw uno::RuntimeException();
++    }
++
++    PK11_DestroyContext( m_pContext, PR_TRUE );
++    m_pContext = NULL;
++    m_bDisposed = true;
++
++    aResult.realloc( nResultLen );
++    return aResult;
++}
++
+diff --git a/xmlsecurity/source/xmlsec/nss/digestcontext.hxx b/xmlsecurity/source/xmlsec/nss/digestcontext.hxx
+new file mode 100644
+index 0000000..8f9ef47
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/digestcontext.hxx
+@@ -0,0 +1,68 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef _DIGESTCONTEXT_HXX
++#define _DIGESTCONTEXT_HXX
++
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++
++#include <cppuhelper/implbase1.hxx>
++#include <osl/mutex.hxx>
++
++class ODigestContext : public cppu::WeakImplHelper1< ::com::sun::star::xml::crypto::XDigestContext >
++{
++private:
++    ::osl::Mutex m_aMutex;
++
++    PK11Context* m_pContext;
++    sal_Int32 m_nDigestLength;
++    bool m_b1KData;
++    sal_Int32 m_nDigested;
++
++    bool m_bDisposed;
++    bool m_bBroken;
++
++public:
++    ODigestContext( PK11Context* pContext, sal_Int32 nDigestLength, bool b1KData )
++    : m_pContext( pContext )
++    , m_nDigestLength( nDigestLength )
++    , m_b1KData( b1KData )
++    , m_nDigested( 0 )
++    , m_bDisposed( false )
++    , m_bBroken( false )
++    {}
++
++    virtual ~ODigestContext();
++
++
++    // XDigestContext
++    virtual void SAL_CALL updateDigest( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++    virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL finalizeDigestAndDispose() throw (::com::sun::star::lang::DisposedException, ::com::sun::star::uno::RuntimeException);
++};
++
++#endif
++
+diff --git a/xmlsecurity/source/xmlsec/nss/makefile.mk b/xmlsecurity/source/xmlsec/nss/makefile.mk
+index de6a059..0875de9 100644
+--- a/xmlsecurity/source/xmlsec/nss/makefile.mk
++++ b/xmlsecurity/source/xmlsec/nss/makefile.mk
+@@ -41,12 +41,6 @@ ENABLE_EXCEPTIONS = TRUE
+ CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS)
+ .ENDIF
+ 
+-.IF "$(CRYPTO_ENGINE)" != "nss"
+-LIBTARGET=NO
+-.ENDIF
+-
+-.IF "$(CRYPTO_ENGINE)" == "nss"
+-
+ .IF "$(WITH_MOZILLA)" == "NO" || "$(ENABLE_NSS_MODULE)"!="YES"
+ .IF "$(SYSTEM_MOZILLA)" != "YES"
+ @all:
+@@ -93,7 +87,11 @@ $(MOZ_INC)$/profile \
+ -I$(MOZ_INC)$/embed_base
+ .ENDIF
+ 
+-CDEFS += -DXMLSEC_CRYPTO_NSS -DXMLSEC_NO_XSLT
++.IF "$(CRYPTO_ENGINE)" == "nss"
++CDEFS += -DXMLSEC_CRYPTO_NSS
++.ENDIF
++
++CDEFS += -DXMLSEC_NO_XSLT
+ 
+ # --- Files --------------------------------------------------------
+ 
+@@ -109,13 +107,19 @@ SOLARINC += -I$(NSS_INC)
+ .ENDIF
+ 
+ SLOFILES = \
++	$(SLO)$/nssinitializer.obj \
++	$(SLO)$/digestcontext.obj \
++	$(SLO)$/ciphercontext.obj \
++	$(SLO)$/xsec_nss.obj
++
++.IF "$(CRYPTO_ENGINE)" == "nss"
++SLOFILES += \
+     $(SLO)$/securityenvironment_nssimpl.obj \
+     $(SLO)$/xmlencryption_nssimpl.obj \
+     $(SLO)$/xmlsecuritycontext_nssimpl.obj \
+     $(SLO)$/xmlsignature_nssimpl.obj \
+     $(SLO)$/x509certificate_nssimpl.obj \
+     $(SLO)$/seinitializer_nssimpl.obj \
+-    $(SLO)$/xsec_nss.obj \
+         $(SLO)$/secerror.obj
+ 
+ 
+diff --git a/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx b/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
+new file mode 100644
+index 0000000..ded3295
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx
+@@ -0,0 +1,521 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_xmlsecurity.hxx"
++
++/*
++ * Turn off DEBUG Assertions
++ */
++#ifdef _DEBUG
++    #define _DEBUG_WAS_DEFINED _DEBUG
++    #undef _DEBUG
++#else
++    #undef _DEBUG_WAS_DEFINED
++#endif
++
++/*
++ * and turn off the additional virtual methods which are part of some interfaces when compiled
++ * with debug
++ */
++#ifdef DEBUG
++    #define DEBUG_WAS_DEFINED DEBUG
++    #undef DEBUG
++#else
++    #undef DEBUG_WAS_DEFINED
++#endif
++
++
++#include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
++#include <com/sun/star/xml/crypto/CipherID.hpp>
++
++#include <sal/types.h>
++#include <rtl/instance.hxx>
++#include <rtl/bootstrap.hxx>
++#include <rtl/string.hxx>
++#include <rtl/strbuf.hxx>
++#include <osl/file.hxx>
++#include <osl/thread.h>
++#include <tools/debug.hxx>
++#include <rtl/logfile.hxx>
++
++#include "seinitializer_nssimpl.hxx"
++#include "../diagnose.hxx"
++
++#include "securityenvironment_nssimpl.hxx"
++#include "digestcontext.hxx"
++#include "ciphercontext.hxx"
++
++#include <nspr.h>
++#include <cert.h>
++#include <nss.h>
++#include <pk11pub.h>
++#include <secmod.h>
++#include <nssckbi.h>
++
++
++namespace css = ::com::sun::star;
++namespace cssu = css::uno;
++namespace cssl = css::lang;
++namespace cssxc = css::xml::crypto;
++
++using namespace xmlsecurity;
++using namespace com::sun::star;
++using ::rtl::OUString;
++using ::rtl::OString;
++
++#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.NSSInitializer_NssImpl"
++
++#define ROOT_CERTS "Root Certs for OpenOffice.org"
++
++extern "C" void nsscrypto_finalize();
++
++
++namespace
++{
++
++bool nsscrypto_initialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF, bool & out_nss_init );
++
++struct InitNSSInitialize
++{
++    css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF;
++
++    InitNSSInitialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF )
++    : mxMSF( xMSF )
++    {
++    }
++
++    bool * operator()()
++        {
++            static bool bInitialized = false;
++            bool bNSSInit = false;
++            bInitialized = nsscrypto_initialize( mxMSF, bNSSInit );
++            if (bNSSInit)
++                atexit(nsscrypto_finalize );
++             return & bInitialized;
++        }
++};
++
++struct GetNSSInitStaticMutex
++{
++    ::osl::Mutex* operator()()
++    {
++        static ::osl::Mutex aNSSInitMutex;
++        return &aNSSInitMutex;
++    }
++};
++
++void deleteRootsModule()
++{
++    SECMODModule *RootsModule = 0;
++    SECMODModuleList *list = SECMOD_GetDefaultModuleList();
++    SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
++    SECMOD_GetReadLock(lock);
++
++    while (!RootsModule && list)
++    {
++        SECMODModule *module = list->module;
++
++        for (int i=0; i < module->slotCount; i++)
++        {
++            PK11SlotInfo *slot = module->slots[i];
++            if (PK11_IsPresent(slot))
++            {
++                if (PK11_HasRootCerts(slot))
++                {
++                    xmlsec_trace("The root certifificates module \"%s"
++                              "\" is already loaded: \n%s",
++                              module->commonName,  module->dllName);
++
++                    RootsModule = SECMOD_ReferenceModule(module);
++                    break;
++                }
++            }
++        }
++        list = list->next;
++    }
++    SECMOD_ReleaseReadLock(lock);
++
++    if (RootsModule)
++    {
++        PRInt32 modType;
++        if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType))
++        {
++            xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName);
++        }
++        else
++        {
++            xmlsec_trace("Failed to delete \"%s\" : \n%s",
++                      RootsModule->commonName, RootsModule->dllName);
++        }
++        SECMOD_DestroyModule(RootsModule);
++        RootsModule = 0;
++    }
++}
++
++::rtl::OString getMozillaCurrentProfile( const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF )
++{
++    ::rtl::OString sResult;
++    // first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER"
++    char* pEnv = getenv( "MOZILLA_CERTIFICATE_FOLDER" );
++    if ( pEnv )
++    {
++        sResult = ::rtl::OString( pEnv );
++        RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", sResult.getStr() );
++    }
++    else
++    {
++        mozilla::MozillaProductType productTypes[4] = {
++            mozilla::MozillaProductType_Thunderbird,
++            mozilla::MozillaProductType_Mozilla,
++            mozilla::MozillaProductType_Firefox,
++            mozilla::MozillaProductType_Default };
++        int nProduct = 4;
++
++        uno::Reference<uno::XInterface> xInstance = rxMSF->createInstance(
++            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) );
++        OSL_ENSURE( xInstance.is(), "failed to create instance" );
++
++        uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap
++            =  uno::Reference<mozilla::XMozillaBootstrap>(xInstance,uno::UNO_QUERY);
++        OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" );
++
++        if (xMozillaBootstrap.is())
++        {
++            for (int i=0; i<nProduct; i++)
++            {
++                ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]);
++
++                if (profile != NULL && profile.getLength()>0)
++                {
++                    ::rtl::OUString sProfilePath = xMozillaBootstrap->getProfilePath( productTypes[i], profile );
++                    sResult = ::rtl::OUStringToOString( sProfilePath, osl_getThreadTextEncoding() );
++                    RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using Mozilla Profile: %s", sResult.getStr() );
++                }
++            }
++        }
++
++        RTL_LOGFILE_PRODUCT_TRACE( "XMLSEC: No Mozilla Profile found!" );
++    }
++
++    return sResult;
++}
++
++//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write
++//the roots certificate module (libnssckbi.so), which they use, into the
++//profile. This module will then already be loaded during NSS_Init (and the
++//other init functions). This fails in two cases. First, FF3 was used to create
++//the profile, or possibly used that profile before, and second the profile was
++//used on a different platform.
++//
++//Then one needs to add the roots module oneself. This should be done with
++//SECMOD_LoadUserModule rather then SECMOD_AddNewModule. The latter would write
++//the location of the roots module to the profile, which makes FF2 and TB2 use
++//it instead of there own module.
++//
++//When using SYSTEM_MOZILLA then the libnss3.so lib is typically found in
++///usr/lib. This folder may, however, NOT contain the roots certificate
++//module. That is, just providing the library name in SECMOD_LoadUserModule or
++//SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH
++//contains an FF or TB installation.
++//ATTENTION: DO NOT call this function directly instead use initNSS
++//return true - whole initialization was successful
++//param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite
++//was successful and therefor NSS_Shutdown should be called when terminating.
++bool nsscrypto_initialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF, bool & out_nss_init )
++{
++    bool return_value = true;
++
++    // this method must be called only once, no need for additional lock
++    rtl::OString sCertDir;
++
++    (void) xMSF;
++#ifdef XMLSEC_CRYPTO_NSS
++    if ( xMSF.is() )
++        sCertDir = getMozillaCurrentProfile( xMSF );
++#endif
++    xmlsec_trace( "Using profile: %s", sCertDir.getStr() );
++
++    PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ;
++
++    // there might be no profile
++    if ( sCertDir.getLength() > 0 )
++    {
++        if( NSS_InitReadWrite( sCertDir.getStr() ) != SECSuccess )
++        {
++            xmlsec_trace("Initializing NSS with profile failed.");
++            char * error = NULL;
++
++            PR_GetErrorText(error);
++            if (error)
++                xmlsec_trace("%s",error);
++            return false ;
++        }
++    }
++    else
++    {
++        xmlsec_trace("Initializing NSS without profile.");
++        if ( NSS_NoDB_Init(NULL) != SECSuccess )
++        {
++            xmlsec_trace("Initializing NSS without profile failed.");
++            char * error = NULL;
++            PR_GetErrorText(error);
++            if (error)
++                xmlsec_trace("%s",error);
++            return false ;
++        }
++    }
++    out_nss_init = true;
++
++#ifdef XMLSEC_CRYPTO_NSS
++#if defined SYSTEM_MOZILLA
++    if (!SECMOD_HasRootCerts())
++    {
++#endif
++        deleteRootsModule();
++
++#if defined SYSTEM_MOZILLA
++        OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("libnssckbi"SAL_DLLEXTENSION));
++#else
++        OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("${OOO_BASE_DIR}/program/libnssckbi"SAL_DLLEXTENSION));
++#endif
++        ::rtl::Bootstrap::expandMacros(rootModule);
++
++        OUString rootModulePath;
++        if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath))
++        {
++            ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding());
++            ::rtl::OStringBuffer pkcs11moduleSpec;
++            pkcs11moduleSpec.append("name=\"");
++            pkcs11moduleSpec.append(ROOT_CERTS);
++            pkcs11moduleSpec.append("\" library=\"");
++            pkcs11moduleSpec.append(ospath.getStr());
++            pkcs11moduleSpec.append("\"");
++
++            SECMODModule * RootsModule =
++                SECMOD_LoadUserModule(
++                    const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()),
++                    0, // no parent
++                    PR_FALSE); // do not recurse
++
++            if (RootsModule)
++            {
++
++                bool found = RootsModule->loaded;
++
++                SECMOD_DestroyModule(RootsModule);
++                RootsModule = 0;
++                if (found)
++                    xmlsec_trace("Added new root certificate module "
++                              "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
++                else
++                {
++                    xmlsec_trace("FAILED to load the new root certificate module "
++                              "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
++                    return_value = false;
++                }
++            }
++            else
++            {
++                xmlsec_trace("FAILED to add new root certifice module: "
++                          "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
++                return_value = false;
++
++            }
++        }
++        else
++        {
++            xmlsec_trace("Adding new root certificate module failed.");
++            return_value = false;
++        }
++#if SYSTEM_MOZILLA
++    }
++#endif
++#endif
++
++    return return_value;
++}
++
++
++// must be extern "C" because we pass the function pointer to atexit
++extern "C" void nsscrypto_finalize()
++{
++    SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS);
++
++    if (RootsModule)
++    {
++
++        if (SECSuccess == SECMOD_UnloadUserModule(RootsModule))
++        {
++            xmlsec_trace("Unloaded module \""ROOT_CERTS"\".");
++        }
++        else
++        {
++            xmlsec_trace("Failed unloadeding module \""ROOT_CERTS"\".");
++        }
++        SECMOD_DestroyModule(RootsModule);
++    }
++    else
++    {
++        xmlsec_trace("Unloading module \""ROOT_CERTS
++                  "\" failed because it was not found.");
++    }
++    PK11_LogoutAll();
++    NSS_Shutdown();
++}
++} // namespace
++
++ONSSInitializer::ONSSInitializer(
++    const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF)
++    :mxMSF( rxMSF )
++{
++}
++
++ONSSInitializer::~ONSSInitializer()
++{
++}
++
++bool ONSSInitializer::initNSS( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF )
++{
++    return *rtl_Instance< bool, InitNSSInitialize, ::osl::MutexGuard, GetNSSInitStaticMutex >
++                ::create( InitNSSInitialize( xMSF ), GetNSSInitStaticMutex() );
++}
++
++css::uno::Reference< css::xml::crypto::XDigestContext > SAL_CALL ONSSInitializer::getDigestContext( ::sal_Int32 nDigestID, const css::uno::Sequence< css::beans::NamedValue >& aParams )
++    throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
++{
++    SECOidTag nNSSDigestID = SEC_OID_UNKNOWN;
++    sal_Int32 nDigestLength = 0;
++    bool b1KData = false;
++    if ( nDigestID == css::xml::crypto::DigestID::SHA256
++      || nDigestID == css::xml::crypto::DigestID::SHA256_1K )
++    {
++        nNSSDigestID = SEC_OID_SHA256;
++        nDigestLength = 32;
++        b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA256_1K );
++    }
++    else if ( nDigestID == css::xml::crypto::DigestID::SHA1
++           || nDigestID == css::xml::crypto::DigestID::SHA1_1K )
++    {
++        nNSSDigestID = SEC_OID_SHA1;
++        nDigestLength = 20;
++        b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA1_1K );
++    }
++    else
++        throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected digest requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 );
++
++    if ( aParams.getLength() )
++        throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for digest creation." ) ), css::uno::Reference< css::uno::XInterface >(), 2 );
++
++    css::uno::Reference< css::xml::crypto::XDigestContext > xResult;
++    if( initNSS( mxMSF ) )
++    {
++        PK11Context* pContext = PK11_CreateDigestContext( nNSSDigestID );
++        if ( pContext && PK11_DigestBegin( pContext ) == SECSuccess )
++            xResult = new ODigestContext( pContext, nDigestLength, b1KData );
++    }
++
++    return xResult;
++}
++
++css::uno::Reference< css::xml::crypto::XCipherContext > SAL_CALL ONSSInitializer::getCipherContext( ::sal_Int32 nCipherID, const css::uno::Sequence< ::sal_Int8 >& aKey, const css::uno::Sequence< ::sal_Int8 >& aInitializationVector, ::sal_Bool bEncryption, const css::uno::Sequence< css::beans::NamedValue >& aParams )
++    throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
++{
++    CK_MECHANISM_TYPE nNSSCipherID = 0;
++    bool bW3CPadding = false;
++    if ( nCipherID == css::xml::crypto::CipherID::AES_CBC_W3C_PADDING )
++    {
++        nNSSCipherID = CKM_AES_CBC;
++        bW3CPadding = true;
++
++        if ( aKey.getLength() != 16 && aKey.getLength() != 24 && aKey.getLength() != 32 )
++            throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected key length." ) ), css::uno::Reference< css::uno::XInterface >(), 2 );
++
++        if ( aParams.getLength() )
++            throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for cipher creation." ) ), css::uno::Reference< css::uno::XInterface >(), 5 );
++    }
++    else
++        throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected cipher requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 );
++
++    css::uno::Reference< css::xml::crypto::XCipherContext > xResult;
++    if( initNSS( mxMSF ) )
++    {
++        if ( aInitializationVector.getLength() != PK11_GetIVLength( nNSSCipherID ) )
++            throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected length of initialization vector." ) ), css::uno::Reference< css::uno::XInterface >(), 3 );
++
++        xResult = OCipherContext::Create( nNSSCipherID, aKey, aInitializationVector, bEncryption, bW3CPadding );
++    }
++
++    return xResult;
++}
++
++rtl::OUString ONSSInitializer_getImplementationName ()
++    throw (cssu::RuntimeException)
++{
++
++    return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
++}
++
++sal_Bool SAL_CALL ONSSInitializer_supportsService( const rtl::OUString& ServiceName )
++    throw (cssu::RuntimeException)
++{
++    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( NSS_SERVICE_NAME ));
++}
++
++cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer_getSupportedServiceNames(  )
++    throw (cssu::RuntimeException)
++{
++    cssu::Sequence < rtl::OUString > aRet(1);
++    rtl::OUString* pArray = aRet.getArray();
++    pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( NSS_SERVICE_NAME ) );
++    return aRet;
++}
++
++cssu::Reference< cssu::XInterface > SAL_CALL ONSSInitializer_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr)
++    throw( cssu::Exception )
++{
++    return (cppu::OWeakObject*) new ONSSInitializer( rSMgr );
++}
++
++/* XServiceInfo */
++rtl::OUString SAL_CALL ONSSInitializer::getImplementationName()
++    throw (cssu::RuntimeException)
++{
++    return ONSSInitializer_getImplementationName();
++}
++sal_Bool SAL_CALL ONSSInitializer::supportsService( const rtl::OUString& rServiceName )
++    throw (cssu::RuntimeException)
++{
++    return ONSSInitializer_supportsService( rServiceName );
++}
++cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer::getSupportedServiceNames(  )
++    throw (cssu::RuntimeException)
++{
++    return ONSSInitializer_getSupportedServiceNames();
++}
++
+diff --git a/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx b/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
+new file mode 100644
+index 0000000..6e7fed1
+--- /dev/null
++++ b/xmlsecurity/source/xmlsec/nss/nssinitializer.hxx
+@@ -0,0 +1,90 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef _NSSINITIALIZER_HXX
++#define _NSSINITIALIZER_HXX
++
++#include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
++#include <com/sun/star/xml/crypto/XCipherContextSupplier.hpp>
++#include <com/sun/star/lang/XServiceInfo.hpp>
++#include <com/sun/star/lang/XMultiServiceFactory.hpp>
++
++#include <cppuhelper/implbase3.hxx>
++
++#define NSS_SERVICE_NAME "com.sun.star.xml.crypto.NSSInitializer"
++
++class ONSSInitializer : public cppu::WeakImplHelper3
++<
++    ::com::sun::star::xml::crypto::XDigestContextSupplier,
++    ::com::sun::star::xml::crypto::XCipherContextSupplier,
++    ::com::sun::star::lang::XServiceInfo
++>
++{
++protected:
++    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
++
++    ONSSInitializer()
++    {}
++
++public:
++    ONSSInitializer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &rxMSF );
++    virtual ~ONSSInitializer();
++
++    bool initNSS( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &xMSF );
++
++    /* XDigestContextSupplier */
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext > SAL_CALL getDigestContext( ::sal_Int32 nDigestID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aParams ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
++
++    /* XCipherContextSupplier */
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > SAL_CALL getCipherContext( ::sal_Int32 nCipherID, const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aKey, const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aInitializationVector, ::sal_Bool bEncryption, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aParams ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
++
++    /* XServiceInfo */
++    virtual rtl::OUString SAL_CALL getImplementationName()
++        throw (::com::sun::star::uno::RuntimeException);
++
++    virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName )
++        throw (::com::sun::star::uno::RuntimeException);
++
++    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
++        throw (::com::sun::star::uno::RuntimeException);
++};
++
++rtl::OUString ONSSInitializer_getImplementationName()
++    throw ( ::com::sun::star::uno::RuntimeException );
++
++sal_Bool SAL_CALL ONSSInitializer_supportsService( const rtl::OUString& ServiceName )
++    throw ( ::com::sun::star::uno::RuntimeException );
++
++com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL ONSSInitializer_getSupportedServiceNames()
++    throw ( ::com::sun::star::uno::RuntimeException );
++
++com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
++SAL_CALL ONSSInitializer_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr )
++    throw ( ::com::sun::star::uno::Exception );
++
++#endif
++
+diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
+index f184600..c1573e8 100644
+--- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
++++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
+@@ -89,7 +89,29 @@ extern X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* ) ;
+ struct UsageDescription
+ {
+     SECCertificateUsage usage;
+-    char const * const description;
++    char const * description;
++
++    UsageDescription()
++    : usage( certificateUsageCheckAllUsages )
++    , description( NULL )
++    {}
++
++    UsageDescription( SECCertificateUsage i_usage, char const* i_description )
++    : usage( i_usage )
++    , description( i_description )
++    {}
++
++    UsageDescription( const UsageDescription& aDescription )
++    : usage( aDescription.usage )
++    , description( aDescription.description )
++    {}
++
++    UsageDescription& operator =( const UsageDescription& aDescription )
++    {
++        usage = aDescription.usage;
++        description = aDescription.description;
++        return *this;
++    }
+ };
+         
+ 
+@@ -868,14 +890,12 @@ verifyCertificate( const Reference< csss::XCertificate >& aCert,
+         // certificateUsageAnyCA
+         // certificateUsageProtectedObjectSigner                            
+    
+-        UsageDescription arUsages[] =
+-        {
+-           {certificateUsageSSLClient, "certificateUsageSSLClient" },
+-           {certificateUsageSSLServer, "certificateUsageSSLServer" },
+-           {certificateUsageSSLCA, "certificateUsageSSLCA" },
+-           {certificateUsageEmailSigner, "certificateUsageEmailSigner"}, //only usable for end certs
+-           {certificateUsageEmailRecipient, "certificateUsageEmailRecipient"}
+-        };
++        UsageDescription arUsages[5];
++        arUsages[0] = UsageDescription( certificateUsageSSLClient, "certificateUsageSSLClient"  );
++        arUsages[1] = UsageDescription( certificateUsageSSLServer, "certificateUsageSSLServer"  );
++        arUsages[2] = UsageDescription( certificateUsageSSLCA, "certificateUsageSSLCA"  );
++        arUsages[3] = UsageDescription( certificateUsageEmailSigner, "certificateUsageEmailSigner" );
++        arUsages[4] = UsageDescription( certificateUsageEmailRecipient, "certificateUsageEmailRecipient" );
+ 
+         int numUsages = SAL_N_ELEMENTS(arUsages);
+         for (int i = 0; i < numUsages; i++)
+diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx
+index b9041e2..18dadf0 100644
+--- a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx
++++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx
+@@ -52,7 +52,6 @@
+ 
+ 
+ #include <sal/types.h>
+-#include "rtl/instance.hxx"
+ #include "rtl/bootstrap.hxx"
+ #include "rtl/string.hxx"
+ #include "rtl/strbuf.hxx"
+@@ -62,327 +61,34 @@
+ #include <rtl/logfile.hxx>
+ 
+ #include "seinitializer_nssimpl.hxx"
+-#include "../diagnose.hxx"
+-
+ #include "securityenvironment_nssimpl.hxx"
+-#include <com/sun/star/mozilla/XMozillaBootstrap.hpp>
+ 
+-#include "nspr.h"
+-#include "cert.h"
+-#include "nss.h"
+-#include "secmod.h"
+-#include "nssckbi.h"
++#include <nspr.h>
++#include <cert.h>
++#include <nss.h>
++#include <pk11pub.h>
++#include <secmod.h>
++#include <nssckbi.h>
+ 
+ 
+-namespace cssu = com::sun::star::uno;
+-namespace cssl = com::sun::star::lang;
+-namespace cssxc = com::sun::star::xml::crypto;
++namespace css = ::com::sun::star;
++namespace cssu = css::uno;
++namespace cssl = css::lang;
++namespace cssxc = css::xml::crypto;
+ 
+-using namespace xmlsecurity;
+ using namespace com::sun::star;
+ using ::rtl::OUString;
+ using ::rtl::OString;
+ 
+-#define SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer"
++#define SE_SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer"
+ #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.SEInitializer_NssImpl"
+ #define SECURITY_ENVIRONMENT "com.sun.star.xml.crypto.SecurityEnvironment"
+ #define SECURITY_CONTEXT "com.sun.star.xml.crypto.XMLSecurityContext"
+ 
+-
+-#define ROOT_CERTS "Root Certs for OpenOffice.org"
+-
+-
+-extern "C" void nsscrypto_finalize();
+-
+-
+-namespace
+-{
+-
+-bool nsscrypto_initialize( const char * sProfile, bool & out_nss_init);
+-
+-struct InitNSSInitialize
+-{
+-    //path to the database folder
+-    const OString m_sProfile;
+-    InitNSSInitialize(const OString & sProfile): m_sProfile(sProfile) {};
+-    bool * operator()()
+-        {
+-            static bool bInitialized = false;
+-            bool bNSSInit = false;
+-            bInitialized = nsscrypto_initialize(m_sProfile.getStr(), bNSSInit);
+-            if (bNSSInit)
+-                atexit(nsscrypto_finalize );
+-             return & bInitialized;
+-            
+-        }
+-};
+-
+-bool * initNSS(const OString & sProfile)
+-{
+-    return rtl_Instance< bool, InitNSSInitialize,
+-        ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
+-            InitNSSInitialize(sProfile), ::osl::GetGlobalMutex());
+-}
+-
+-void deleteRootsModule()
+-{
+-    SECMODModule *RootsModule = 0;
+-    SECMODModuleList *list = SECMOD_GetDefaultModuleList();
+-    SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
+-    SECMOD_GetReadLock(lock);
+-    
+-    while (!RootsModule && list)
+-    {
+-        SECMODModule *module = list->module;
+- 
+-        for (int i=0; i < module->slotCount; i++)
+-        {
+-            PK11SlotInfo *slot = module->slots[i];
+-            if (PK11_IsPresent(slot))
+-            {
+-                if (PK11_HasRootCerts(slot))
+-                {
+-                    xmlsec_trace("The root certifificates module \"%s"
+-                              "\" is already loaded: \n%s",
+-                              module->commonName,  module->dllName);
+-
+-                    RootsModule = SECMOD_ReferenceModule(module);
+-                    break;
+-                }
+-            }
+-        }
+-        list = list->next;
+-    }
+-    SECMOD_ReleaseReadLock(lock);
+- 
+-    if (RootsModule)
+-    {
+-        PRInt32 modType;
+-        if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType))
+-        {
+-            xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName);
+-        }
+-        else
+-        {
+-            xmlsec_trace("Failed to delete \"%s\" : \n%s",
+-                      RootsModule->commonName, RootsModule->dllName);
+-        }
+-        SECMOD_DestroyModule(RootsModule);
+-        RootsModule = 0;
+-    }
+-}
+-
+-//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write
+-//the roots certificate module (libnssckbi.so), which they use, into the
+-//profile. This module will then already be loaded during NSS_Init (and the
+-//other init functions). This fails in two cases. First, FF3 was used to create
+-//the profile, or possibly used that profile before, and second the profile was
+-//used on a different platform.
+-//
+-//Then one needs to add the roots module oneself. This should be done with
+-//SECMOD_LoadUserModule rather then SECMOD_AddNewModule. The latter would write
+-//the location of the roots module to the profile, which makes FF2 and TB2 use
+-//it instead of there own module.
+-//
+-//When using SYSTEM_MOZILLA then the libnss3.so lib is typically found in
+-///usr/lib. This folder may, however, NOT contain the roots certificate
+-//module. That is, just providing the library name in SECMOD_LoadUserModule or
+-//SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH
+-//contains an FF or TB installation.
+-//ATTENTION: DO NOT call this function directly instead use initNSS
+-//return true - whole initialization was successful
+-//param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite
+-//was successful and therefor NSS_Shutdown should be called when terminating.
+-bool nsscrypto_initialize( const char* token, bool & out_nss_init )
+-{
+-    bool return_value = true;
+-
+-    xmlsec_trace("Using profile: %s", token);
+-
+-    PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ;
+-
+-    //token may be an empty string
+-    if (token != NULL && strlen(token) > 0)
+-    {
+-        if( NSS_InitReadWrite( token ) != SECSuccess )
+-        {
+-            xmlsec_trace("Initializing NSS with profile failed.");
+-            char * error = NULL;
+-            
+-            PR_GetErrorText(error);
+-            if (error)
+-                xmlsec_trace("%s",error);
+-            return false ;
+-        }
+-    }
+-    else
+-    {
+-        xmlsec_trace("Initializing NSS without profile.");
+-        if ( NSS_NoDB_Init(NULL) != SECSuccess )
+-        {
+-            xmlsec_trace("Initializing NSS without profile failed.");
+-            char * error = NULL;
+-            PR_GetErrorText(error);
+-            if (error)
+-                xmlsec_trace("%s",error);
+-            return false ;
+-        }
+-    }
+-    out_nss_init = true;
+-    
+-#if defined SYSTEM_MOZILLA
+-    if (!SECMOD_HasRootCerts())
+-    {
+-#endif
+-        deleteRootsModule();
+-        
+-#if defined SYSTEM_MOZILLA
+-        OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("libnssckbi"SAL_DLLEXTENSION));
+-#else
+-        OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("${OOO_BASE_DIR}/program/libnssckbi"SAL_DLLEXTENSION));
+-#endif
+-        ::rtl::Bootstrap::expandMacros(rootModule);
+-        
+-        OUString rootModulePath;
+-        if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath))
+-        {
+-            ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding());
+-            ::rtl::OStringBuffer pkcs11moduleSpec;
+-            pkcs11moduleSpec.append("name=\"");
+-            pkcs11moduleSpec.append(ROOT_CERTS);
+-            pkcs11moduleSpec.append("\" library=\"");
+-            pkcs11moduleSpec.append(ospath.getStr());
+-            pkcs11moduleSpec.append("\"");
+- 
+-            SECMODModule * RootsModule =
+-                SECMOD_LoadUserModule(
+-                    const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()), 
+-                    0, // no parent 
+-                    PR_FALSE); // do not recurse
+-                
+-            if (RootsModule)
+-            {
+-                
+-                bool found = RootsModule->loaded;
+-                    
+-                SECMOD_DestroyModule(RootsModule);
+-                RootsModule = 0;
+-                if (found)
+-                    xmlsec_trace("Added new root certificate module "
+-                              "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
+-                else
+-                {
+-                    xmlsec_trace("FAILED to load the new root certificate module "
+-                              "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
+-                    return_value = false;
+-                }
+-            }
+-            else
+-            {
+-                xmlsec_trace("FAILED to add new root certifice module: "
+-                          "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr());
+-                return_value = false;
+-
+-            }
+-        }
+-        else
+-        {
+-            xmlsec_trace("Adding new root certificate module failed.");
+-            return_value = false;
+-        }
+-#if SYSTEM_MOZILLA
+-    }
+-#endif
+-
+-    return return_value;
+-}
+-
+-
+-// must be extern "C" because we pass the function pointer to atexit
+-extern "C" void nsscrypto_finalize()
+-{
+-    SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS);
+-
+-    if (RootsModule)
+-    {
+-        
+-        if (SECSuccess == SECMOD_UnloadUserModule(RootsModule))
+-        {
+-            xmlsec_trace("Unloaded module \""ROOT_CERTS"\".");
+-        }
+-        else
+-        {
+-            xmlsec_trace("Failed unloadeding module \""ROOT_CERTS"\".");
+-        }
+-        SECMOD_DestroyModule(RootsModule);
+-    }
+-    else
+-    {
+-        xmlsec_trace("Unloading module \""ROOT_CERTS
+-                  "\" failed because it was not found.");
+-    }
+-    PK11_LogoutAll();
+-    NSS_Shutdown();
+-}
+-
+-
+-bool getMozillaCurrentProfile(
+-    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF,
+-    rtl::OUString& profilePath)
+-{
+-    /*
+-     * first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER"
+-     */ 
+-    char * env = getenv("MOZILLA_CERTIFICATE_FOLDER");
+-    if (env)
+-    {
+-        profilePath = rtl::OUString::createFromAscii( env );
+-        RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", rtl::OUStringToOString( profilePath, RTL_TEXTENCODING_ASCII_US ).getStr() );
+-        return true;
+-    }
+-    else
+-    {
+-        mozilla::MozillaProductType productTypes[4] = {
+-            mozilla::MozillaProductType_Thunderbird,
+-            mozilla::MozillaProductType_Mozilla,
+-            mozilla::MozillaProductType_Firefox,
+-            mozilla::MozillaProductType_Default };
+-        
+-        uno::Reference<uno::XInterface> xInstance = rxMSF->createInstance(
+-            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) );
+-        OSL_ENSURE( xInstance.is(), "failed to create instance" );
+-        
+-        uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap 
+-            =  uno::Reference<mozilla::XMozillaBootstrap>(xInstance,uno::UNO_QUERY);
+-        OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" );
+-        
+-        if (xMozillaBootstrap.is())
+-        {
+-            int nProduct = 4;
+-            for (int i=0; i<nProduct; i++)
+-            {
+-                ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]);
+-                
+-                if (profile != NULL && profile.getLength()>0)
+-                {
+-                    profilePath = xMozillaBootstrap->getProfilePath(productTypes[i],profile);
+-                    RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using Mozilla Profile: %s", rtl::OUStringToOString( profilePath, RTL_TEXTENCODING_ASCII_US ).getStr() );
+-                    return true;
+-                }
+-            }
+-        }
+-        
+-        RTL_LOGFILE_PRODUCT_TRACE( "XMLSEC: No Mozilla Profile found!" );
+-        return false;
+-    }
+-}
+-
+-} // namespace
+-
+ SEInitializer_NssImpl::SEInitializer_NssImpl(
+-    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF)
+-    :mxMSF( rxMSF )
++    const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF )
+ {
++    mxMSF = rxMSF;
+ }
+ 
+ SEInitializer_NssImpl::~SEInitializer_NssImpl() 
+@@ -391,36 +97,13 @@ SEInitializer_NssImpl::~SEInitializer_NssImpl()
+ 
+ /* XSEInitializer */
+ cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL 
+-    SEInitializer_NssImpl::createSecurityContext(
+-    const rtl::OUString& sCertDB )
++    SEInitializer_NssImpl::createSecurityContext( const ::rtl::OUString& )
+     throw (cssu::RuntimeException)
+ {
+     CERTCertDBHandle    *pCertHandle = NULL ;
+ 
+-    rtl::OString sCertDir;
+-    if( sCertDB.getLength() ) 
+-    {
+-        sCertDir = rtl::OUStringToOString(sCertDB, RTL_TEXTENCODING_ASCII_US);
+-    }
+-    else
+-    {
+-        static rtl::OString* pDefaultCertDir = NULL;
+-        if ( !pDefaultCertDir )
+-        {
+-            pDefaultCertDir = new rtl::OString; 
+-            rtl::OUString ouCertDir;
+-
+-            if ( getMozillaCurrentProfile(mxMSF, ouCertDir) )
+-                *pDefaultCertDir = rtl::OUStringToOString(ouCertDir, RTL_TEXTENCODING_ASCII_US);
+-        }
+-        sCertDir = *pDefaultCertDir;
+-        
+-    }
+-
+-    if( ! *initNSS( sCertDir.getStr() ) )
+-    {
++    if( !initNSS( mxMSF ) )
+         return NULL;
+-    }
+ 
+     pCertHandle = CERT_GetDefaultCertDB() ;
+ 
+@@ -477,18 +160,18 @@ rtl::OUString SEInitializer_NssImpl_getImplementationName ()
+ sal_Bool SAL_CALL SEInitializer_NssImpl_supportsService( const rtl::OUString& ServiceName ) 
+     throw (cssu::RuntimeException)
+ {
+-    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
++    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SE_SERVICE_NAME )) || ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( NSS_SERVICE_NAME ));
+ }
+ 
+ cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl_getSupportedServiceNames(  ) 
+     throw (cssu::RuntimeException)
+ {
+-    cssu::Sequence < rtl::OUString > aRet(1);
++    cssu::Sequence < rtl::OUString > aRet(2);
+     rtl::OUString* pArray = aRet.getArray();
+-    pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
++    pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SE_SERVICE_NAME ) );
++    pArray[1] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( NSS_SERVICE_NAME ) );
+     return aRet;
+ }
+-#undef SERVICE_NAME
+ 
+ cssu::Reference< cssu::XInterface > SAL_CALL SEInitializer_NssImpl_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr)
+     throw( cssu::Exception )
+diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx
+index 53e5129..2092b92 100644
+--- a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx
++++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx
+@@ -31,37 +31,19 @@
+ 
+ #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
+ #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
+-#include <com/sun/star/lang/XUnoTunnel.hpp>
+-#include <com/sun/star/lang/XServiceInfo.hpp>
+-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+-#include <cppuhelper/implbase2.hxx>
++
++#include <cppuhelper/implbase1.hxx>
+ 
+ #include <libxml/tree.h>
+ 
+-class SEInitializer_NssImpl : public cppu::WeakImplHelper2 
++#include "nssinitializer.hxx"
++
++class SEInitializer_NssImpl : public cppu::ImplInheritanceHelper1
+ < 
+-    com::sun::star::xml::crypto::XSEInitializer,
+-    com::sun::star::lang::XServiceInfo
++    ONSSInitializer,
++    ::com::sun::star::xml::crypto::XSEInitializer
+ >
+-/****** SEInitializer_NssImpl.hxx/CLASS SEInitializer_NssImpl ***********
+- *
+- *   NAME
+- *	SEInitializer_NssImpl -- Class to initialize a Security Context
+- *	instance
+- *
+- *   FUNCTION
+- *	Use this class to initialize a XmlSec based Security Context
+- *	instance. After this instance is used up, use this class to free this
+- *	instance.
+- *
+- *   AUTHOR
+- *	Michael Mi
+- *	Email: michael.mi at sun.com
+- ******************************************************************************/
+ {
+-private:
+-    com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > mxMSF;
+-    
+ public:
+     SEInitializer_NssImpl(const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF);
+     virtual ~SEInitializer_NssImpl();
+@@ -69,7 +51,7 @@ public:
+     /* XSEInitializer */
+     virtual com::sun::star::uno::Reference< 
+         com::sun::star::xml::crypto::XXMLSecurityContext >
+-        SAL_CALL createSecurityContext( const rtl::OUString& certDB )
++        SAL_CALL createSecurityContext( const ::rtl::OUString& )
+         throw (com::sun::star::uno::RuntimeException);
+         
+     virtual void SAL_CALL freeSecurityContext( const com::sun::star::uno::Reference<
+diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+index 71a0221..93c9839 100644
+--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
++++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+@@ -120,13 +120,13 @@ sal_Int16 SAL_CALL X509Certificate_NssImpl :: getVersion() throw ( ::com::sun::s
+         //Convert the time to readable local time
+         PR_ExplodeTime( notBefore, PR_LocalTimeParameters, &explTime ) ;
+ 
+-        dateTime.HundredthSeconds = explTime.tm_usec / 1000 ;
+-        dateTime.Seconds = explTime.tm_sec ;
+-        dateTime.Minutes = explTime.tm_min ;
+-        dateTime.Hours = explTime.tm_hour ;
+-        dateTime.Day = explTime.tm_mday ;
+-        dateTime.Month = explTime.tm_month+1 ;
+-        dateTime.Year = explTime.tm_year ;
++        dateTime.HundredthSeconds = static_cast< sal_Int16 >( explTime.tm_usec / 1000  );
++        dateTime.Seconds = static_cast< sal_Int16 >( explTime.tm_sec  );
++        dateTime.Minutes = static_cast< sal_Int16 >( explTime.tm_min  );
++        dateTime.Hours = static_cast< sal_Int16 >( explTime.tm_hour  );
++        dateTime.Day = static_cast< sal_Int16 >( explTime.tm_mday  );
++        dateTime.Month = static_cast< sal_Int16 >( explTime.tm_month+1  );
++        dateTime.Year = static_cast< sal_Int16 >( explTime.tm_year  );
+ 
+         return dateTime ;
+     } else {
+@@ -149,13 +149,13 @@ sal_Int16 SAL_CALL X509Certificate_NssImpl :: getVersion() throw ( ::com::sun::s
+         //Convert the time to readable local time
+         PR_ExplodeTime( notAfter, PR_LocalTimeParameters, &explTime ) ;
+ 
+-        dateTime.HundredthSeconds = explTime.tm_usec / 1000 ;
+-        dateTime.Seconds = explTime.tm_sec ;
+-        dateTime.Minutes = explTime.tm_min ;
+-        dateTime.Hours = explTime.tm_hour ;
+-        dateTime.Day = explTime.tm_mday ;
+-        dateTime.Month = explTime.tm_month+1 ;
+-        dateTime.Year = explTime.tm_year ;
++        dateTime.HundredthSeconds = static_cast< sal_Int16 >( explTime.tm_usec / 1000  );
++        dateTime.Seconds = static_cast< sal_Int16 >( explTime.tm_sec  );
++        dateTime.Minutes = static_cast< sal_Int16 >( explTime.tm_min  );
++        dateTime.Hours = static_cast< sal_Int16 >( explTime.tm_hour  );
++        dateTime.Day = static_cast< sal_Int16 >( explTime.tm_mday  );
++        dateTime.Month = static_cast< sal_Int16 >( explTime.tm_month+1  );
++        dateTime.Year = static_cast< sal_Int16 >( explTime.tm_year  );
+ 
+         return dateTime ;
+     } else {
+diff --git a/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx b/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx
+index a226d96..7b2fbd0 100644
+--- a/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx
++++ b/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx
+@@ -57,21 +57,41 @@ void* SAL_CALL nss_component_getFactory( const sal_Char* pImplName , void* pServ
+     void* pRet = 0;
+     Reference< XSingleServiceFactory > xFactory ;
+ 
+-    if( pImplName != NULL && pServiceManager != NULL ) {
+-        if( XMLSignature_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) {
++    if( pImplName != NULL && pServiceManager != NULL )
++    {
++#ifdef XMLSEC_CRYPTO_NSS
++        if( SEInitializer_NssImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
++            xFactory = Reference< XSingleServiceFactory >( createSingleFactory(
++                reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
++                OUString::createFromAscii( pImplName ),
++                SEInitializer_NssImpl_createInstance, SEInitializer_NssImpl_getSupportedServiceNames() ) );
++        }
++        else if( XMLSignature_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
+             xFactory = XMLSignature_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+-        } else if( XMLSecurityContext_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) {
++        }
++        else if( XMLSecurityContext_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
+             xFactory = XMLSecurityContext_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+-        } else if( SecurityEnvironment_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) {
++        }
++        else if( SecurityEnvironment_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
+             xFactory = SecurityEnvironment_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+-        } else if( XMLEncryption_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) {
++        }
++        else if( XMLEncryption_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
+             xFactory = XMLEncryption_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+-        } else if( SEInitializer_NssImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) {
++        }
++#else
++        if( ONSSInitializer_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) )
++        {
+             xFactory = Reference< XSingleServiceFactory >( createSingleFactory(
+                 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+                 OUString::createFromAscii( pImplName ),
+-                SEInitializer_NssImpl_createInstance, SEInitializer_NssImpl_getSupportedServiceNames() ) );
++                ONSSInitializer_createInstance, ONSSInitializer_getSupportedServiceNames() ) );
+         }
++#endif
+     }
+ 
+     if( xFactory.is() ) {
+diff --git a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
+index 1eeec66..935f0d6 100644
+--- a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
++++ b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
+@@ -94,9 +94,7 @@ Reference< XInterface > SerialNumberAdapterImpl_createInstance(
+ extern "C"
+ {
+ 
+-#if defined( XMLSEC_CRYPTO_NSS )
+ extern void* nss_component_getFactory( const sal_Char*, void*, void* );
+-#endif
+ 
+ #if defined( XMLSEC_CRYPTO_MSCRYPTO )
+ extern void* mscrypt_component_getFactory( const sal_Char*, void*, void* );
+@@ -141,11 +139,9 @@ void* SAL_CALL component_getFactory( const sal_Char* pImplName , void* pServiceM
+         xFactory->acquire() ;
+         pRet = xFactory.get() ;
+     } else {
+-#if defined( XMLSEC_CRYPTO_NSS )
+         pRet = nss_component_getFactory( pImplName, pServiceManager, pRegistryKey ) ;
+         if( pRet != NULL )
+             return pRet ;
+-#endif
+         
+ #if defined( XMLSEC_CRYPTO_MSCRYPTO )
+         pRet = mscrypt_component_getFactory( pImplName, pServiceManager, pRegistryKey ) ;
+diff --git a/xmlsecurity/util/makefile.mk b/xmlsecurity/util/makefile.mk
+index ff5a952..be64450 100644
+--- a/xmlsecurity/util/makefile.mk
++++ b/xmlsecurity/util/makefile.mk
+@@ -81,10 +81,10 @@ SHL2LIBS= \
+ .IF "$(CRYPTO_ENGINE)" == "mscrypto"
+ SHL2LIBS += \
+     $(SLB)$/xs_mscrypt.lib
+-.ELSE
++.ENDIF
++
+ SHL2LIBS += \
+     $(SLB)$/xs_nss.lib
+-.ENDIF
+ 
+ .ENDIF
+ 
+@@ -118,6 +118,8 @@ SHL2STDLIBS += $(MOZ_NSS_LIBS)
+ 
+ .IF "$(CRYPTO_ENGINE)" == "mscrypto"
+ SHL2STDLIBS+= $(MSCRYPTOLIBS)
++# SHL2STDLIBS+= $(XMLSECLIB) $(LIBXML2LIB) $(NSS3LIB) $(NSPR4LIB) $(PLC4LIB)
++SHL2STDLIBS+= $(NSS3LIB) $(NSPR4LIB)
+ .ELSE
+ SHL2STDLIBS+= $(NSSCRYPTOLIBS)
+ .ENDIF
+@@ -127,10 +129,10 @@ SHL2DEF = $(MISC)$/$(SHL2TARGET).def
+ DEF2NAME = $(SHL2TARGET)
+ .IF "$(CRYPTO_ENGINE)" == "mscrypto"
+ DEF2EXPORTFILE = exports_xsmscrypt.dxp
+-.ELSE
+-DEF2EXPORTFILE = exports_xsnss.dxp
+ .ENDIF
+ 
++DEF2EXPORTFILE = exports_xsnss.dxp
++
+ SRSFILELIST=	\
+                 $(SRS)$/component.srs   \
+                 $(SRS)$/dialogs.srs
+diff --git a/xmlsecurity/util/xsec_xmlsec.component b/xmlsecurity/util/xsec_xmlsec.component
+index de99189..df4c2a7 100644
+--- a/xmlsecurity/util/xsec_xmlsec.component
++++ b/xmlsecurity/util/xsec_xmlsec.component
+@@ -32,6 +32,7 @@
+     <service name="com.sun.star.security.SerialNumberAdapter"/>
+   </implementation>
+   <implementation name="com.sun.star.xml.security.bridge.xmlsec.SEInitializer_NssImpl">
++    <service name="com.sun.star.xml.crypto.NSSInitializer"/>
+     <service name="com.sun.star.xml.crypto.SEInitializer"/>
+   </implementation>
+   <implementation name="com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl">
+diff --git a/xmlsecurity/util/xsec_xmlsec.windows.component b/xmlsecurity/util/xsec_xmlsec.windows.component
+index fb11cc6..7b4ef87 100644
+--- a/xmlsecurity/util/xsec_xmlsec.windows.component
++++ b/xmlsecurity/util/xsec_xmlsec.windows.component
+@@ -31,6 +31,9 @@
+   <implementation name="com.sun.star.security.SerialNumberAdapter">
+     <service name="com.sun.star.security.SerialNumberAdapter"/>
+   </implementation>
++  <implementation name="com.sun.star.xml.security.bridge.xmlsec.NSSInitializer_NssImpl">
++    <service name="com.sun.star.xml.crypto.NSSInitializer"/>
++  </implementation>
+   <implementation name="com.sun.star.xml.security.bridge.xmlsec.SEInitializer_MSCryptImpl">
+     <service name="com.sun.star.xml.crypto.SEInitializer"/>
+   </implementation>
+-- 
+1.7.6.4
+
+From 670427a194e3676f2c49a907ec47b43dc5cbbdae Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman at redhat.com>
+Date: Wed, 9 Nov 2011 08:37:56 +0100
+Subject: [PATCH] Backport reading AES-encrypted ODF 1.2 documents (as
+ genereated by LibO 3.5).
+
+This backports the reading half of CWS mav60 plus <http://cgit.freedesktop.org/
+libreoffice/core/commit/?id=2d775f593abd9bc487ccc60f06aa5a3ca9632056> "Produce
+correct sha256 uri, consume correct uri and original spec typo."  It spans the
+repos components, libs-core, libs-gui, and ure.
+---
+ sfx2/source/appl/appopen.cxx |    5 +++--
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx
+index 6ec4645..84f0cef 100644
+--- a/sfx2/source/appl/appopen.cxx
++++ b/sfx2/source/appl/appopen.cxx
+@@ -288,8 +288,9 @@ private:
+     }
+     catch( const uno::Exception& )
+     {
+-        // unknown error, do not try to ask again
+-        eResult = ::comphelper::DocPasswordVerifierResult_ABORT;
++        // unknown error, report it as wrong password
++        // TODO/LATER: we need an additional way to report unknown problems in this case
++        eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+     }
+     return eResult;
+ }
+-- 
+1.7.6.4
+
+From 467dcc484a6782ffaa2bbb4cc059a68150a4298e Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman at redhat.com>
+Date: Wed, 9 Nov 2011 08:38:58 +0100
+Subject: [PATCH] Backport reading AES-encrypted ODF 1.2 documents (as
+ genereated by LibO 3.5).
+
+This backports the reading half of CWS mav60 plus <http://cgit.freedesktop.org/
+libreoffice/core/commit/?id=2d775f593abd9bc487ccc60f06aa5a3ca9632056> "Produce
+correct sha256 uri, consume correct uri and original spec typo."  It spans the
+repos components, libs-core, libs-gui, and ure.
+---
+ comphelper/inc/comphelper/storagehelper.hxx |    1 +
+ comphelper/source/misc/storagehelper.cxx    |   37 +++++++++++++++++++++++---
+ 2 files changed, 33 insertions(+), 5 deletions(-)
+
+diff --git a/comphelper/inc/comphelper/storagehelper.hxx b/comphelper/inc/comphelper/storagehelper.hxx
+index 2f83331..807c6dd 100644
+--- a/comphelper/inc/comphelper/storagehelper.hxx
++++ b/comphelper/inc/comphelper/storagehelper.hxx
+@@ -45,6 +45,7 @@
+ #define ZIP_STORAGE_FORMAT_STRING		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ZipFormat" ) )
+ #define OFOPXML_STORAGE_FORMAT_STRING	::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) )
+ 
++#define PACKAGE_ENCRYPTIONDATA_SHA256UTF8 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA256UTF8EncryptionKey" ) )
+ #define PACKAGE_ENCRYPTIONDATA_SHA1UTF8   ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA1UTF8EncryptionKey" ) )
+ #define PACKAGE_ENCRYPTIONDATA_SHA1MS1252 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA1MS1252EncryptionKey" ) )
+ 
+diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx
+index f703cd3..112ddf1 100644
+--- a/comphelper/source/misc/storagehelper.cxx
++++ b/comphelper/source/misc/storagehelper.cxx
+@@ -35,6 +35,9 @@
+ #include <com/sun/star/beans/PropertyValue.hpp>
+ #include <com/sun/star/beans/NamedValue.hpp>
+ #include <com/sun/star/beans/IllegalTypeException.hpp>
++#include <com/sun/star/xml/crypto/XDigestContext.hpp>
++#include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
++#include <com/sun/star/xml/crypto/DigestID.hpp>
+ 
+ #include <rtl/digest.h>
+ 
+@@ -427,14 +430,38 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData(
+ {
+     // TODO/LATER: Should not the method be part of DocPasswordHelper?
+     uno::Sequence< beans::NamedValue > aEncryptionData;
++    sal_Int32 nSha1Ind = 0;
+     if ( aPassword.getLength() )
+     {
++        // generate SHA256 start key
++        try
++        {
++            uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
++            if ( !xFactory.is() )
++                throw uno::RuntimeException();
++
++            uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW );
++            uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
++
++            ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) );
++            xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) );
++            uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose();
++
++            aEncryptionData.realloc( ++nSha1Ind );
++            aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
++            aEncryptionData[0].Value <<= aDigest;
++        }
++        catch ( uno::Exception& )
++        {
++            OSL_ENSURE( false, "Can not create SHA256 digest!" );
++        }
++
+         // MS_1252 encoding was used for SO60 document format password encoding,
+         // this encoding supports only a minor subset of nonascii characters,
+         // but for compatibility reasons it has to be used for old document formats
+-        aEncryptionData.realloc( 2 );
+-        aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
+-        aEncryptionData[1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
++        aEncryptionData.realloc( nSha1Ind + 2 );
++        aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
++        aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
+ 
+         rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 };
+ 
+@@ -450,11 +477,11 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData(
+ 
+             if ( nError != rtl_Digest_E_None )
+             {
+-                aEncryptionData.realloc( 0 );
++                aEncryptionData.realloc( nSha1Ind );
+                 break;
+             }
+ 
+-            aEncryptionData[nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
++            aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
+         }
+     }
+ 
+-- 
+1.7.6.4
+
+From cb66db96806b506caa6e1e804c864efbb14e5a91 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman at redhat.com>
+Date: Wed, 9 Nov 2011 08:35:42 +0100
+Subject: [PATCH] Backport reading AES-encrypted ODF 1.2 documents (as
+ genereated by LibO 3.5).
+
+This backports the reading half of CWS mav60 plus <http://cgit.freedesktop.org/
+libreoffice/core/commit/?id=2d775f593abd9bc487ccc60f06aa5a3ca9632056> "Produce
+correct sha256 uri, consume correct uri and original spec typo."  It spans the
+repos components, libs-core, libs-gui, and ure.
+---
+ .../sun/star/embed/XEncryptionProtectedStorage.idl |  118 ++++++++++++++++++++
+ offapi/com/sun/star/embed/makefile.mk              |    1 +
+ offapi/com/sun/star/xml/crypto/CipherID.idl        |   59 ++++++++++
+ offapi/com/sun/star/xml/crypto/DigestID.idl        |   71 ++++++++++++
+ offapi/com/sun/star/xml/crypto/SEInitializer.idl   |    4 +
+ offapi/com/sun/star/xml/crypto/XCipherContext.idl  |   88 +++++++++++++++
+ .../sun/star/xml/crypto/XCipherContextSupplier.idl |   91 +++++++++++++++
+ offapi/com/sun/star/xml/crypto/XDigestContext.idl  |   73 ++++++++++++
+ .../sun/star/xml/crypto/XDigestContextSupplier.idl |   82 ++++++++++++++
+ offapi/com/sun/star/xml/crypto/makefile.mk         |    6 +
+ 10 files changed, 593 insertions(+), 0 deletions(-)
+ create mode 100644 offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/CipherID.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/DigestID.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/XCipherContext.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/XCipherContextSupplier.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/XDigestContext.idl
+ create mode 100644 offapi/com/sun/star/xml/crypto/XDigestContextSupplier.idl
+
+diff --git a/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
+new file mode 100644
+index 0000000..91f1199
+--- /dev/null
++++ b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
+@@ -0,0 +1,118 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_embed_XEncryptionProtectedStorage_idl__
++#define __com_sun_star_embed_XEncryptionProtectedStorage_idl__
++
++#ifndef __com_sun_star_embed_XEncryptionProtectedSource2_idl__
++#include <com/sun/star/embed/XEncryptionProtectedSource2.idl>
++#endif
++
++#ifndef __com_sun_star_beans_NamedValue_idl__
++#include <com/sun/star/beans/NamedValue.idl>
++#endif
++
++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__
++#include <com/sun/star/lang/IllegalArgumentException.idl>
++#endif
++
++#ifndef __com_sun_star_xml_crypto_DigestID_idl__
++#include <com/sun/star/xml/crypto/DigestID.idl>
++#endif
++
++#ifndef __com_sun_star_xml_crypto_CipherID_idl__
++#include <com/sun/star/xml/crypto/CipherID.idl>
++#endif
++
++//============================================================================
++
++module com {  module sun {  module star {  module embed {
++
++//============================================================================
++/** This interface allows to set a password for an object.
++
++    This unpublished interface was introduced into a micro update of
++    LibreOffice 3.4; it is unclear in what exact form it will be included in
++    LibreOffice 3.5.  A corresponding OOo interface (which is also unpublished)
++    is scheduled for inclusion into OOo 3.4 and contains an additional
++    getEncryptionAlgorithms method.
++ */
++interface XEncryptionProtectedStorage: XEncryptionProtectedSource2
++{
++    // -----------------------------------------------------------------------
++    /** allows to set the encryption algorithms for the object.
++        <p>
++        The algorithms will of course be used only for streams that have been
++        marked to be encrypted. If no stream in the storage is marked to be
++        encrypted, the algorithms-related information may have no effect to
++        the result package.
++        </p>
++
++        <p>
++        The following values could be part of the provided sequence:
++        </p>
++        <dl>
++            <dt>StartKeyGenerationAlgorithm</dt>
++            <dd>
++                    specifies the algorithm that was used to generate
++                    the EncryptionKey from the original password; in case
++                    the contents should be decrypted, the algorithm might
++                    be already known by the object; if a different one is
++                    set an exception should be thrown to indicate the
++                    error; it should take values from
++                    <type scope="com::sun::star::xml:crypto">DigestID</type>.
++            </dd>
++            <dt>EncryptionAlgorithm</dt>
++            <dd>
++                    specifies the algorithm that should be used to
++                    encrypt/decrypt the contents; in case the contents
++                    should be decrypted, the algorithm might be already
++                    known by the object; if a different one is set
++                    an exception should be thrown to indicate the error;
++                    it should take values from
++                    <type scope="com::sun::star::xml:crypto">CipherID</type>.
++            </dd>
++            <dt>ChecksumAlgorithm</dt>
++            <dd>
++                    specifies the algorithm that was used to generate
++                    the checksum of the encrypted data; in case
++                    the contents should be decrypted, the algorithm might
++                    be already known by the object; if a different one is
++                    set an exception should be thrown to indicate the
++                    error; it should take values from
++                    <type scope="com::sun::star::xml:crypto">DigestID</type>.
++            </dd>
++        </dl>
++     */
++    void setEncryptionAlgorithms( [in] sequence< ::com::sun::star::beans::NamedValue > aAlgorithms )
++        raises( ::com::sun::star::lang::IllegalArgumentException );
++};
++
++//============================================================================
++
++}; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/embed/makefile.mk b/offapi/com/sun/star/embed/makefile.mk
+index 8ee156a..c142086 100644
+--- a/offapi/com/sun/star/embed/makefile.mk
++++ b/offapi/com/sun/star/embed/makefile.mk
+@@ -78,6 +78,7 @@ IDLFILES=\
+     XLinkFactory.idl\
+     XEncryptionProtectedSource.idl\
+     XEncryptionProtectedSource2.idl\
++    XEncryptionProtectedStorage.idl\
+     XInplaceClient.idl\
+     XInsertObjectDialog.idl\
+     XWindowSupplier.idl\
+diff --git a/offapi/com/sun/star/xml/crypto/CipherID.idl b/offapi/com/sun/star/xml/crypto/CipherID.idl
+new file mode 100644
+index 0000000..a59c034
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/CipherID.idl
+@@ -0,0 +1,59 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_CipherID_idl__
++#define __com_sun_star_xml_crypto_CipherID_idl__
++
++
++//============================================================================
++
++module com { module sun { module star { module xml { module crypto {
++
++//============================================================================
++/** The constant set contains identifiers of supported cipher-creation
++    algorithms.
++
++    @see <type>XCipherContextSupplier</type>
++    @since OOo 3.4
++*/
++constants CipherID
++{
++    //------------------------------------------------------------------------
++    /** identifier of AES algorithm in CBC mode with W3C padding
++     */
++    const long AES_CBC_W3C_PADDING = 1;
++
++    //------------------------------------------------------------------------
++    /** identifier of the Blowfish algorithm in 8-bit CFB mode
++     */
++    const long BLOWFISH_CFB_8 = 2;
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/DigestID.idl b/offapi/com/sun/star/xml/crypto/DigestID.idl
+new file mode 100644
+index 0000000..bd2c61c
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/DigestID.idl
+@@ -0,0 +1,71 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_DigestID_idl__
++#define __com_sun_star_xml_crypto_DigestID_idl__
++
++
++//============================================================================
++
++module com { module sun { module star { module xml { module crypto {
++
++//============================================================================
++/** The constant set contains identifiers of supported digest-creation
++    algorithms.
++
++    @see <type>XDigestContextSupplier</type>
++    @since OOo 3.4
++*/
++constants DigestID
++{
++    //------------------------------------------------------------------------
++    /** identifier of SHA-1 algorithm
++     */
++    const long SHA1 = 1;
++
++    //------------------------------------------------------------------------
++    /** identifier of SHA-256 algorithm
++     */
++    const long SHA256 = 2;
++
++    //------------------------------------------------------------------------
++    /** identifier of SHA-1 algorithm that is applied to the first kilobyte
++        of data.
++     */
++    const long SHA1_1K = 3;
++
++    //------------------------------------------------------------------------
++    /** identifier of SHA-256 algorithm that is applied to the first kilobyte
++        of data.
++     */
++    const long SHA256_1K = 4;
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/SEInitializer.idl b/offapi/com/sun/star/xml/crypto/SEInitializer.idl
+index beec5ef..5a9ff7d 100644
+--- a/offapi/com/sun/star/xml/crypto/SEInitializer.idl
++++ b/offapi/com/sun/star/xml/crypto/SEInitializer.idl
+@@ -36,6 +36,8 @@
+ #include <com/sun/star/uno/Exception.idl>
+ 
+ #include <com/sun/star/xml/crypto/XSEInitializer.idl>
++#include <com/sun/star/xml/crypto/XDigestContextSupplier.idl>
++#include <com/sun/star/xml/crypto/XCipherContextSupplier.idl>
+ 
+ #include <com/sun/star/lang/XServiceInfo.idl>
+ 
+@@ -46,6 +48,8 @@ module com { module sun { module star { module xml { module crypto {
+  */
+ service SEInitializer {
+     interface com::sun::star::xml::crypto::XSEInitializer ;
++    interface ::com::sun::star::xml::crypto::XDigestContextSupplier;
++    interface ::com::sun::star::xml::crypto::XCipherContextSupplier;
+     interface com::sun::star::lang::XServiceInfo ;
+ };
+ 
+diff --git a/offapi/com/sun/star/xml/crypto/XCipherContext.idl b/offapi/com/sun/star/xml/crypto/XCipherContext.idl
+new file mode 100644
+index 0000000..fb84139
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/XCipherContext.idl
+@@ -0,0 +1,88 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_xciphercontext_idl_
++#define __com_sun_star_xml_crypto_xciphercontext_idl_
++
++#ifndef __com_sun_star_uno_XInterface_idl__
++#include <com/sun/star/uno/XInterface.idl>
++#endif
++
++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__
++#include <com/sun/star/lang/IllegalArgumentException.idl>
++#endif
++
++#ifndef __com_sun_star_lang_DisposedException_idl__
++#include <com/sun/star/lang/DisposedException.idl>
++#endif
++
++//============================================================================
++
++ module com {  module sun {  module star {  module xml { module crypto {
++
++//============================================================================
++/** This interface allows to encrypt/decrypt data using the cipher context.
++    <p>
++    The algorithm as well as encryption data are specified on object creation.
++    </p>
++
++    @see <type>XCipherContextSupplier</type>
++    @since OOo 3.4
++ */
++interface XCipherContext : com::sun::star::uno::XInterface
++{
++    //------------------------------------------------------------------------
++    /** encrypts/decrypts the data using the cipher.
++        <p>
++        Please have in mind, the cipher object state might depend from the
++        already encrypted/decrypted data ( it depends from the used
++        algorithm ).
++        </p>
++
++        <p>
++        Whether the object does encryption or decryption is specified by
++        creation of the object.
++        </p>
++
++        @param aData
++            data that should be encrypted/decrypted
++     */
++    sequence<byte> convertWithCipherContext( [in] sequence< byte > aData )
++        raises( ::com::sun::star::lang::IllegalArgumentException,
++                ::com::sun::star::lang::DisposedException );
++
++    //------------------------------------------------------------------------
++    /** finalizes cipher and disposes context.
++     */
++    sequence<byte> finalizeCipherContextAndDispose()
++        raises( ::com::sun::star::lang::DisposedException );
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/XCipherContextSupplier.idl b/offapi/com/sun/star/xml/crypto/XCipherContextSupplier.idl
+new file mode 100644
+index 0000000..115cf7b
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/XCipherContextSupplier.idl
+@@ -0,0 +1,91 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_xciphercontextsupplier_idl_
++#define __com_sun_star_xml_crypto_xciphercontextsupplier_idl_
++
++#ifndef __com_sun_star_uno_XInterface_idl__
++#include <com/sun/star/uno/XInterface.idl>
++#endif
++
++#ifndef __com_sun_star_beans_NamedValue_idl__
++#include <com/sun/star/beans/NamedValue.idl>
++#endif
++
++#ifndef __com_sun_star_xml_crypto_XCipherContext_idl__
++#include <com/sun/star/xml/crypto/XCipherContext.idl>
++#endif
++
++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__
++#include <com/sun/star/lang/IllegalArgumentException.idl>
++#endif
++
++//============================================================================
++
++ module com {  module sun {  module star {  module xml { module crypto {
++
++//============================================================================
++/** This interface allows to get an object that allows to encrypt/decrypt data
++    using the specified algorithm.
++
++    @since OOo 3.4
++ */
++interface XCipherContextSupplier : com::sun::star::uno::XInterface
++{
++    //------------------------------------------------------------------------
++    /** returns an object that allows to encrypt/decrypt data.
++
++        @param nCipherID
++            the internal ID specifying the algorithm,
++            should take value from <type>CipherID</type>
++
++        @param aKey
++            the key that should be used for the encryption
++
++        @param aInitializationVector
++            the initialization vector that should be used for the encryption
++
++        @param bEncryption
++            whether an encryption or decryption cipher should be created
++            <TRUE/> - Encryption
++            <FALSE/> - Decryption
++
++        @param aParams
++            optional parameters that could be used to initialize the cipher,
++
++        @throws ::com::sun::star::lang::IllegalArgumentException
++            one of provided arguments is illegal
++     */
++
++    XCipherContext getCipherContext( [in] long nCipherID, [in] sequence< byte > aKey, [in] sequence< byte > aInitializationVector, [in] boolean bEncryption, [in] sequence< ::com::sun::star::beans::NamedValue > aParams )
++        raises( ::com::sun::star::lang::IllegalArgumentException );
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/XDigestContext.idl b/offapi/com/sun/star/xml/crypto/XDigestContext.idl
+new file mode 100644
+index 0000000..36c1d99
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/XDigestContext.idl
+@@ -0,0 +1,73 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_xdigestcontext_idl_
++#define __com_sun_star_xml_crypto_xdigestcontext_idl_
++
++#ifndef __com_sun_star_uno_XInterface_idl__
++#include <com/sun/star/uno/XInterface.idl>
++#endif
++
++#ifndef __com_sun_star_lang_DisposedException_idl__
++#include <com/sun/star/lang/DisposedException.idl>
++#endif
++
++//============================================================================
++
++ module com {  module sun {  module star {  module xml { module crypto {
++
++//============================================================================
++/** This interface allows to generate the digest.
++    <p>
++    The algorithm to generate the digest is specified on object creation.
++    </p>
++
++    @see <type>XDigestContextSupplier</type>
++    @since OOo 3.4
++ */
++interface XDigestContext : com::sun::star::uno::XInterface
++{
++    //------------------------------------------------------------------------
++    /** update the digest with the given data.
++
++        @param aData
++            data that should be used to update the digest
++     */
++    void updateDigest( [in] sequence< byte > aData )
++        raises( ::com::sun::star::lang::DisposedException );
++
++    //------------------------------------------------------------------------
++    /** finalizes digest and disposes context.
++     */
++    sequence<byte> finalizeDigestAndDispose()
++        raises( ::com::sun::star::lang::DisposedException );
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/XDigestContextSupplier.idl b/offapi/com/sun/star/xml/crypto/XDigestContextSupplier.idl
+new file mode 100644
+index 0000000..edb77a5
+--- /dev/null
++++ b/offapi/com/sun/star/xml/crypto/XDigestContextSupplier.idl
+@@ -0,0 +1,82 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_xml_crypto_xdigestcontextsupplier_idl_
++#define __com_sun_star_xml_crypto_xdigestcontextsupplier_idl_
++
++#ifndef __com_sun_star_uno_XInterface_idl__
++#include <com/sun/star/uno/XInterface.idl>
++#endif
++
++#ifndef __com_sun_star_beans_NamedValue_idl__
++#include <com/sun/star/beans/NamedValue.idl>
++#endif
++
++#ifndef __com_sun_star_xml_crypto_XDigestContext_idl__
++#include <com/sun/star/xml/crypto/XDigestContext.idl>
++#endif
++
++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__
++#include <com/sun/star/lang/IllegalArgumentException.idl>
++#endif
++
++//============================================================================
++
++ module com {  module sun {  module star {  module xml { module crypto {
++
++//============================================================================
++/** This interface allows to get an object to generate a digest of a specified
++    format.
++
++    @since OOo 3.4
++ */
++interface XDigestContextSupplier : com::sun::star::uno::XInterface
++{
++    //------------------------------------------------------------------------
++    /** returns an object that allows to generate the specified digest.
++
++        @param nDigestID
++            the internal ID specifying the algorithm,
++            should take value from <type>DigestID</type>
++
++        @param aParams
++            optional parameters that could be used to initialize the digest,
++            for example, it could contain a key and etc.
++
++        @throws ::com::sun::star::lang::IllegalArgumentException
++            one of provided arguments is illegal
++     */
++    XDigestContext getDigestContext(
++                [in] long nDigestID,
++                [in] sequence< ::com::sun::star::beans::NamedValue > aParams )
++        raises( ::com::sun::star::lang::IllegalArgumentException );
++};
++
++//============================================================================
++
++}; }; }; }; };
++
++#endif
+diff --git a/offapi/com/sun/star/xml/crypto/makefile.mk b/offapi/com/sun/star/xml/crypto/makefile.mk
+index 4aa3957..c03b2a7 100644
+--- a/offapi/com/sun/star/xml/crypto/makefile.mk
++++ b/offapi/com/sun/star/xml/crypto/makefile.mk
+@@ -58,6 +58,12 @@ IDLFILES=\
+     XMLSignatureException.idl     \
+     XMLEncryptionException.idl     \
+     XUriBinding.idl    \
++    CipherID.idl \
++    DigestID.idl \
++    XCipherContext.idl \
++    XCipherContextSupplier.idl \
++    XDigestContext.idl \
++    XDigestContextSupplier.idl \
+     SecurityOperationStatus.idl
+ 
+ # ------------------------------------------------------------------
+-- 
+1.7.6.4
+
diff --git a/libreoffice.spec b/libreoffice.spec
index 5fe3892..738011d 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -27,7 +27,7 @@ Summary:        Free Software Productivity Suite
 Name:           libreoffice
 Epoch:          1
 Version:        3.4.4.2
-Release:        1%{?dist}
+Release:        2%{?dist}
 License:        LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and (CDDL or GPLv2) and Public Domain
 Group:          Applications/Productivity
 URL:            http://www.documentfoundation.org/develop
@@ -123,6 +123,7 @@ Patch27: 0001-Resolves-rhbz-738255-avoid-crash-on-NULL-pointer.patch
 Patch28: 0001-avoid-using-com.sun.org-apis.patch
 Patch29: 0001-add-Oracle-Java-1.7.0-recognition.patch
 Patch30: 0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch
+Patch31: Backport-reading-AES-encrypted-ODF-1.2-documents.patch
 
 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 %define instdir %{_libdir}
@@ -795,6 +796,7 @@ mv -f redhat.soc extras/source/palettes/standard.soc
 %patch28 -p1 -b .avoid-using-com.sun.org-apis.patch
 %patch29 -p1 -b .add-Oracle-Java-1.7.0-recognition.patch
 %patch30 -p1 -b .fdo32665-handle-that-FreeSerif-lacks-some-.patch
+%patch31 -p1 -b .Backport-reading-AES-encrypted-ODF-1.2-documents.patch
 
 # these are horribly incomplete--empty translations and copied english
 # strings with spattering of translated strings
@@ -2096,6 +2098,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
 %{basisinstdir}/program/kde-open-url
 
 %changelog
+* Thu Nov 10 2011 Stephan Bergmann <sbergman at redhat.com> - 3.4.4.2-2
+- Patch to backport reading AES-encrypted ODF 1.2 documents
+
 * Thu Nov 03 2011 David Tardon <dtardon at redhat.com> - 3.4.4.2-1
 - 3.4.4 rc2
 


More information about the scm-commits mailing list