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 +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 "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 + #include + +-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 + #include + #include ++#include ++#include ++ ++#include ++ + #include + #include + #include ++#include + + #include + +@@ -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 ++#include ++#include ++#include ++#include ++ + #include + #include + #include +-#include +-#include + + #include + + 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 + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++#ifndef _ZIP_PACKAGE_ENTRY_HXX ++#define _ZIP_PACKAGE_ENTRY_HXX ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++#ifndef _ZIP_PACKAGE_STREAM_HXX ++#define _ZIP_PACKAGE_STREAM_HXX ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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(pBuffer, nSecondLength); ++ aBuffer = uno::Sequence( 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& aPass); +- static void decodeBase64(com::sun::star::uno::Sequence& aPass, const rtl::OUString& sBuffer); ++ static void encodeBase64(rtl::OUStringBuffer& aStrBuffer, const com::sun::star::uno::Sequence& aPass); ++ static void decodeBase64(com::sun::star::uno::Sequence& 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 + #include + #include ++#include ++#include + #include + + 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 + #include + ++#include ++ + #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 + #include + ++#include + + #include + #include +@@ -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 ( this ) + , static_cast ( this ) +- , static_cast ( this ) ); ++ , static_cast ( this ) ++ , static_cast ( 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 + #include + #include +-#include ++#include + #include + #include + #include +@@ -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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +- +-// MARKER(update_precomp.py): autogen include statement, do not remove +-#include "precompiled_package.hxx" +-#include +-#include +-#include +-#include +-#include // 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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +-#ifndef _ENTRY_INPUT_STREAM_HXX +-#define _ENTRY_INPUT_STREAM_HXX +- +-#include // helper for implementations +-#include +-#include +-#include +-#include +-#include +-#include +-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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +- +-// MARKER(update_precomp.py): autogen include statement, do not remove +-#include "precompiled_package.hxx" +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +-#ifndef _XFILE_STREAM_HXX +-#define _XFILE_STREAM_HXX +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +- +-// MARKER(update_precomp.py): autogen include statement, do not remove +-#include "precompiled_package.hxx" +-#include +- +-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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +-#ifndef _XMEMORY_STREAM_HXX +-#define _XMEMORY_STREAM_HXX +- +-#include +- +-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 + #include + #include ++#include ++ + #include +-#include + #include + #include + #include +@@ -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 + #include + #include ++#include ++ + #include + #include + #include +@@ -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 + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include + #include + /* + #include + #include + */ ++ ++#include "blowfishcontext.hxx" ++#include "sha1context.hxx" + #include + #include + #include +@@ -47,10 +58,10 @@ + + #include + +-#include // for memcpy + #include + + #include ++#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 + + #include ++#include + ++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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++// MARKER(update_precomp.py): autogen include statement, do not remove ++#include "precompiled_package.hxx" ++ ++#include ++#include ++ ++#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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++#ifndef _BLOWFISHCONTEXT_HXX ++#define _BLOWFISHCONTEXT_HXX ++ ++#include ++ ++#include ++#include ++ ++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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++// MARKER(update_precomp.py): autogen include statement, do not remove ++#include "precompiled_package.hxx" ++ ++#include ++#include ++ ++#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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++#ifndef _SHA1CONTEXT_HXX ++#define _SHA1CONTEXT_HXX ++ ++#include ++ ++#include ++#include ++ ++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 + #include + #include ++#include ++#include + #include + #include + #include +@@ -83,6 +85,7 @@ + #include + #include + #include ++#include + + 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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +-#ifndef _ZIP_PACKAGE_ENTRY_HXX +-#define _ZIP_PACKAGE_ENTRY_HXX +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 + #include + #include ++#include ++#include + + + #include +@@ -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 +- * +- * for a copy of the LGPLv3 License. +- * +- ************************************************************************/ +-#ifndef _ZIP_PACKAGE_STREAM_HXX +-#define _ZIP_PACKAGE_STREAM_HXX +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#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 + + #include ++#include + + #include + +@@ -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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++#ifndef _CIPHERCONTEXT_HXX ++#define _CIPHERCONTEXT_HXX ++ ++#include ++ ++#include ++#include ++#include ++ ++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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++#include ++ ++#include ++#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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++#ifndef _DIGESTCONTEXT_HXX ++#define _DIGESTCONTEXT_HXX ++ ++#include ++ ++#include ++#include ++ ++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 ++ * ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "seinitializer_nssimpl.hxx" ++#include "../diagnose.hxx" ++ ++#include "securityenvironment_nssimpl.hxx" ++#include "digestcontext.hxx" ++#include "ciphercontext.hxx" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++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 xInstance = rxMSF->createInstance( ++ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) ); ++ OSL_ENSURE( xInstance.is(), "failed to create instance" ); ++ ++ uno::Reference xMozillaBootstrap ++ = uno::Reference(xInstance,uno::UNO_QUERY); ++ OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" ); ++ ++ if (xMozillaBootstrap.is()) ++ { ++ for (int i=0; igetDefaultProfile(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(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 ++ * ++ * for a copy of the LGPLv3 License. ++ * ++ ************************************************************************/ ++ ++#ifndef _NSSINITIALIZER_HXX ++#define _NSSINITIALIZER_HXX ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 +-#include "rtl/instance.hxx" + #include "rtl/bootstrap.hxx" + #include "rtl/string.hxx" + #include "rtl/strbuf.hxx" +@@ -62,327 +61,34 @@ + #include + + #include "seinitializer_nssimpl.hxx" +-#include "../diagnose.hxx" +- + #include "securityenvironment_nssimpl.hxx" +-#include + +-#include "nspr.h" +-#include "cert.h" +-#include "nss.h" +-#include "secmod.h" +-#include "nssckbi.h" ++#include ++#include ++#include ++#include ++#include ++#include + + +-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(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 xInstance = rxMSF->createInstance( +- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) ); +- OSL_ENSURE( xInstance.is(), "failed to create instance" ); +- +- uno::Reference xMozillaBootstrap +- = uno::Reference(xInstance,uno::UNO_QUERY); +- OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" ); +- +- if (xMozillaBootstrap.is()) +- { +- int nProduct = 4; +- for (int i=0; igetDefaultProfile(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 + #include +-#include +-#include +-#include +-#include ++ ++#include + + #include + +-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@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 @@ + + + ++ + + + +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 @@ + + + ++ ++ ++ + + + +-- +1.7.6.4 + +From 670427a194e3676f2c49a907ec47b43dc5cbbdae Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +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 "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 +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 "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 + #include + #include ++#include ++#include ++#include + + #include + +@@ -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 +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 "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 ++ * ++ * 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 ++#endif ++ ++#ifndef __com_sun_star_beans_NamedValue_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_xml_crypto_DigestID_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_xml_crypto_CipherID_idl__ ++#include ++#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. ++

++ 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. ++

++ ++

++ The following values could be part of the provided sequence: ++

++
++
StartKeyGenerationAlgorithm
++
++ 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 ++ DigestID. ++
++
EncryptionAlgorithm
++
++ 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 ++ CipherID. ++
++
ChecksumAlgorithm
++
++ 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 ++ DigestID. ++
++
++ */ ++ 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 ++ * ++ * 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 XCipherContextSupplier ++ @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 ++ * ++ * 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 XDigestContextSupplier ++ @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 + + #include ++#include ++#include + + #include + +@@ -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 ++ * ++ * 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 ++#endif ++ ++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_lang_DisposedException_idl__ ++#include ++#endif ++ ++//============================================================================ ++ ++ module com { module sun { module star { module xml { module crypto { ++ ++//============================================================================ ++/** This interface allows to encrypt/decrypt data using the cipher context. ++

++ The algorithm as well as encryption data are specified on object creation. ++

++ ++ @see XCipherContextSupplier ++ @since OOo 3.4 ++ */ ++interface XCipherContext : com::sun::star::uno::XInterface ++{ ++ //------------------------------------------------------------------------ ++ /** encrypts/decrypts the data using the cipher. ++

++ Please have in mind, the cipher object state might depend from the ++ already encrypted/decrypted data ( it depends from the used ++ algorithm ). ++

++ ++

++ Whether the object does encryption or decryption is specified by ++ creation of the object. ++

++ ++ @param aData ++ data that should be encrypted/decrypted ++ */ ++ sequence convertWithCipherContext( [in] sequence< byte > aData ) ++ raises( ::com::sun::star::lang::IllegalArgumentException, ++ ::com::sun::star::lang::DisposedException ); ++ ++ //------------------------------------------------------------------------ ++ /** finalizes cipher and disposes context. ++ */ ++ sequence 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 ++ * ++ * 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 ++#endif ++ ++#ifndef __com_sun_star_beans_NamedValue_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_xml_crypto_XCipherContext_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__ ++#include ++#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 CipherID ++ ++ @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 ++ - Encryption ++ - 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 ++ * ++ * 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 ++#endif ++ ++#ifndef __com_sun_star_lang_DisposedException_idl__ ++#include ++#endif ++ ++//============================================================================ ++ ++ module com { module sun { module star { module xml { module crypto { ++ ++//============================================================================ ++/** This interface allows to generate the digest. ++

++ The algorithm to generate the digest is specified on object creation. ++

++ ++ @see XDigestContextSupplier ++ @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 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 ++ * ++ * 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 ++#endif ++ ++#ifndef __com_sun_star_beans_NamedValue_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_xml_crypto_XDigestContext_idl__ ++#include ++#endif ++ ++#ifndef __com_sun_star_lang_IllegalArgumentException_idl__ ++#include ++#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 DigestID ++ ++ @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 - 3.4.4.2-2 +- Patch to backport reading AES-encrypted ODF 1.2 documents + * Thu Nov 03 2011 David Tardon - 3.4.4.2-1 - 3.4.4 rc2