From 4be242ce6b91dd23ffa8075bb4eeb05e8bb3d01c Mon Sep 17 00:00:00 2001 From: Miguel Gomez Date: Tue, 2 Apr 2013 15:36:12 +0200 Subject: Allow selecting the tls backend to use in oox from configure Change-Id: Ie82afb1f22caa0b02ddac256e2a0c2a49f19bb15 Reviewed-on: https://gerrit.libreoffice.org/3173 Reviewed-by: Miklos Vajna Tested-by: Miklos Vajna --- config_host.mk.in | 1 + config_host/config_oox.h.in | 13 ++++++ configure.ac | 40 ++++++++++++++++++ oox/Library_oox.mk | 10 +++++ oox/source/core/filterdetect.cxx | 88 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 config_host/config_oox.h.in diff --git a/config_host.mk.in b/config_host.mk.in index 772e5d4bf853..0b7726eb6ec7 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -568,6 +568,7 @@ export TDE_LIBS=$(gb_SPACE)@TDE_LIBS@ export TELEPATHY_CFLAGS=$(gb_SPACE)@TELEPATHY_CFLAGS@ export TELEPATHY_LIBS=$(gb_SPACE)@TELEPATHY_LIBS@ export THES_SYSTEM_DIR=@THES_SYSTEM_DIR@ +export TLS=@TLS@ @x_Cygwin@ export TMP=@TMP_DIRECTORY@ export TMPDIR=@TEMP_DIRECTORY@ export TYPO_EXTENSION_PACK=@TYPO_EXTENSION_PACK@ diff --git a/config_host/config_oox.h.in b/config_host/config_oox.h.in new file mode 100644 index 000000000000..f711fa79477a --- /dev/null +++ b/config_host/config_oox.h.in @@ -0,0 +1,13 @@ +#ifndef CONFIG_OOX_H +#define CONFIG_OOX_H + +/* + +Which TLS backend to use for cryptographic operations. + +*/ + +#define USE_TLS_OPENSSL 0 +#define USE_TLS_NSS 0 + +#endif diff --git a/configure.ac b/configure.ac index 90a2d891cd21..e2f715bab268 100644 --- a/configure.ac +++ b/configure.ac @@ -1271,6 +1271,17 @@ AC_ARG_WITH(package-format, installed, msi. Example: --with-package-format="deb dmg"]), ,) +AC_ARG_WITH(tls, + AS_HELP_STRING([--with-tls], + [Decides which TLS/SSL and cryptographic implementations to use for + LibreOffice's code. Notice that this doesn't apply for depending + libraries like "neon", for example. Default is to use OpenSSL + although NSS is also possible. Notice that selecting NSS restricts + the usage of OpenSSL in LO's code but selecting OpenSSL doesn't + restrict by now the usage of NSS in LO's code. Possible values: + openssl, nss. Example: --with-tls="nss"]), +,) + AC_ARG_WITH(system-libs, AS_HELP_STRING([--with-system-libs], [Use libraries already on system -- enables all --with-system-* flags.]), @@ -8091,6 +8102,34 @@ AC_SUBST(WITH_MOZAB4WIN) AC_SUBST(MSVC80_DLLS) AC_SUBST(MSVC80_DLL_PATH) +dnl =================================================================== +dnl Check for TLS/SSL and cryptographic implementation to use +dnl =================================================================== +AC_MSG_CHECKING([which TLS/SSL and cryptographic implementation to use]) +if test -n "$with_tls"; then + case $with_tls in + openssl) + AC_DEFINE(USE_TLS_OPENSSL) + TLS=OPENSSL + ;; + nss) + AC_DEFINE(USE_TLS_NSS) + TLS=NSS + ;; + *) + AC_MSG_ERROR([unsupported implementation $with_tls. Supported are: +openssl - OpenSSL +nss - Mozilla's Network Security Services (NSS) + ]) + ;; + esac +else + AC_DEFINE(USE_TLS_OPENSSL) + TLS=OPENSSL +fi +AC_MSG_RESULT([$TLS]) +AC_SUBST(TLS) + dnl =================================================================== dnl Check for system NSS dnl =================================================================== @@ -11805,6 +11844,7 @@ AC_CONFIG_HEADERS([config_host/config_global.h]) AC_CONFIG_HEADERS([config_host/config_graphite.h]) AC_CONFIG_HEADERS([config_host/config_kde4.h]) AC_CONFIG_HEADERS([config_host/config_mingw.h]) +AC_CONFIG_HEADERS([config_host/config_oox.h]) AC_CONFIG_HEADERS([config_host/config_telepathy.h]) AC_CONFIG_HEADERS([config_host/config_typesizes.h]) AC_CONFIG_HEADERS([config_host/config_vclplug.h]) diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk index 5cc52aeef036..8d07153cc437 100644 --- a/oox/Library_oox.mk +++ b/oox/Library_oox.mk @@ -81,11 +81,21 @@ $(eval $(call gb_Library_use_libraries,oox,\ $(gb_UWINAPI) \ )) +ifeq ($(TLS),OPENSSL) $(eval $(call gb_Library_use_externals,oox,\ boost_headers \ openssl \ openssl_headers \ )) +else +ifeq ($(TLS),NSS) +$(eval $(call gb_Library_use_externals,oox,\ + boost_headers \ + plc4 \ + nss3 \ +)) +endif +endif $(eval $(call gb_Library_set_componentfile,oox,oox/util/oox)) diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 1bc095fd1395..3d84a94abc40 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -19,11 +19,18 @@ #include "oox/core/filterdetect.hxx" +#include #include #include #include #include +#if USE_TLS_OPENSSL #include +#endif // USE_TLS_OPENSSL +#if USE_TLS_NSS +#include +#include +#endif // USE_TLS_NSS #include #include "oox/core/fastparser.hxx" #include "oox/helper/attributelist.hxx" @@ -373,6 +380,7 @@ bool lclCheckEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const if ( nKeySize == 16 && nVerifierSize == 16 && nVerifierHashSize == 32 ) { // check password +#if USE_TLS_OPENSSL EVP_CIPHER_CTX aes_ctx; EVP_CIPHER_CTX_init( &aes_ctx ); EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); @@ -392,6 +400,37 @@ bool lclCheckEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifierHash, &nOutLen, pnVerifierHash, nVerifierHashSize ); EVP_CIPHER_CTX_cleanup( &aes_ctx ); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + PK11SlotInfo *aSlot( PK11_GetBestSlot( CKM_AES_ECB, NULL ) ); + sal_uInt8 *key( new sal_uInt8[ nKeySize ] ); + (void) memcpy( key, pnKey, nKeySize * sizeof(sal_uInt8) ); + + SECItem keyItem; + keyItem.type = siBuffer; + keyItem.data = key; + keyItem.len = nKeySize; + + PK11SymKey *symKey( PK11_ImportSymKey( aSlot, CKM_AES_ECB, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL ) ); + SECItem *secParam( PK11_ParamFromIV( CKM_AES_ECB, NULL ) ); + PK11Context *encContext( PK11_CreateContextBySymKey( CKM_AES_ECB, CKA_DECRYPT, symKey, secParam ) ); + + int nOutLen(0); + sal_uInt8 pnTmpVerifier[ 16 ]; + (void) memset( pnTmpVerifier, 0, sizeof(pnTmpVerifier) ); + + PK11_CipherOp( encContext, pnTmpVerifier, &nOutLen, sizeof(pnTmpVerifier), const_cast(pnVerifier), nVerifierSize ); + + sal_uInt8 pnTmpVerifierHash[ 32 ]; + (void) memset( pnTmpVerifierHash, 0, sizeof(pnTmpVerifierHash) ); + PK11_CipherOp( encContext, pnTmpVerifierHash, &nOutLen, sizeof(pnTmpVerifierHash), const_cast(pnVerifierHash), nVerifierHashSize ); + + PK11_DestroyContext( encContext, PR_TRUE ); + PK11_FreeSymKey( symKey ); + SECITEM_FreeItem( secParam, PR_TRUE ); + delete[] key; +#endif // USE_TLS_NSS rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); rtl_digest_update( aDigest, pnTmpVerifier, sizeof( pnTmpVerifier ) ); @@ -552,6 +591,11 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript if( bImplemented ) { +#if USE_TLS_NSS + // Initialize NSS, database functions are not needed + NSS_NoDB_Init( NULL ); +#endif // USE_TLS_NSS + /* "VelvetSweatshop" is the built-in default encryption password used by MS Excel for the "workbook protection" feature with password. Try this first before prompting the @@ -579,10 +623,31 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); +#if USE_TLS_OPENSSL EVP_CIPHER_CTX aes_ctx; EVP_CIPHER_CTX_init( &aes_ctx ); EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + // Retrieve the valid key so we can get its size later + SequenceAsHashMap aHashData( aEncryptionData ); + Sequence validKey( aHashData.getUnpackedValueOrDefault( OUString("AES128EncryptionKey"), Sequence() ) ); + + PK11SlotInfo *aSlot( PK11_GetBestSlot( CKM_AES_ECB, NULL ) ); + sal_uInt8 *key = new sal_uInt8[ validKey.getLength() ]; + (void) memcpy( key, aVerifier.getKey(), validKey.getLength() ); + + SECItem keyItem; + keyItem.type = siBuffer; + keyItem.data = key; + keyItem.len = validKey.getLength(); + + PK11SymKey *symKey( PK11_ImportSymKey( aSlot, CKM_AES_ECB, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL ) ); + SECItem *secParam( PK11_ParamFromIV( CKM_AES_ECB, NULL ) ); + PK11Context *encContext( PK11_CreateContextBySymKey( CKM_AES_ECB, CKA_DECRYPT, symKey, secParam ) ); +#endif // USE_TLS_NSS sal_uInt8 pnInBuffer[ 1024 ]; sal_uInt8 pnOutBuffer[ 1024 ]; @@ -591,13 +656,36 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript aEncryptedPackage.skip( 8 ); // decrypted size while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) { +#if USE_TLS_OPENSSL EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + PK11_CipherOp( encContext, pnOutBuffer, &nOutLen, sizeof(pnOutBuffer), pnInBuffer, nInLen ); +#endif // USE_TLS_NSS aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); } +#if USE_TLS_OPENSSL EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + uint final; + PK11_DigestFinal( encContext, pnOutBuffer, &final, nInLen - nOutLen ); + nOutLen = final; +#endif // USE_TLS_NSS aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); +#if USE_TLS_OPENSSL EVP_CIPHER_CTX_cleanup( &aes_ctx ); +#endif // USE_TLS_OPENSSL + +#if USE_TLS_NSS + PK11_DestroyContext( encContext, PR_TRUE ); + PK11_FreeSymKey( symKey ); + SECITEM_FreeItem( secParam, PR_TRUE ); + delete[] key; +#endif // USE_TLS_NSS xDecryptedPackage->flush(); aDecryptedPackage.seekToStart(); -- cgit