diff options
Diffstat (limited to 'xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx')
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx | 387 |
1 files changed, 3 insertions, 384 deletions
diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx index 2cccd079f8e5..3e969b093047 100644 --- a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx +++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx @@ -49,13 +49,7 @@ #undef DEBUG_WAS_DEFINED #endif - -#include <com/sun/star/mozilla/XMozillaBootstrap.hpp> -#include <com/sun/star/xml/crypto/DigestID.hpp> -#include <com/sun/star/xml/crypto/CipherID.hpp> - #include <sal/types.h> -#include <rtl/instance.hxx> #include <rtl/bootstrap.hxx> #include <rtl/string.hxx> #include <rtl/strbuf.hxx> @@ -65,11 +59,7 @@ #include <rtl/logfile.hxx> #include "seinitializer_nssimpl.hxx" -#include "../diagnose.hxx" - #include "securityenvironment_nssimpl.hxx" -#include "digestcontext.hxx" -#include "ciphercontext.hxx" #include <nspr.h> #include <cert.h> @@ -90,316 +80,13 @@ using ::rtl::OUString; using ::rtl::OString; #define SE_SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer" -#define NSS_SERVICE_NAME "com.sun.star.xml.crypto.NSSInitializer" #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 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; - } -}; - -bool * initNSS( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF ) -{ - return rtl_Instance< bool, InitNSSInitialize, ::osl::MutexGuard, GetNSSInitStaticMutex > - ::create( InitNSSInitialize( xMSF ), GetNSSInitStaticMutex() ); -} - -void deleteRootsModule() -{ - SECMODModule *RootsModule = 0; - SECMODModuleList *list = SECMOD_GetDefaultModuleList(); - SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); - SECMOD_GetReadLock(lock); - - while (!RootsModule && list) - { - SECMODModule *module = list->module; - - for (int i=0; i < module->slotCount; i++) - { - PK11SlotInfo *slot = module->slots[i]; - if (PK11_IsPresent(slot)) - { - if (PK11_HasRootCerts(slot)) - { - xmlsec_trace("The root certifificates module \"%s" - "\" is already loaded: \n%s", - module->commonName, module->dllName); - - RootsModule = SECMOD_ReferenceModule(module); - break; - } - } - } - list = list->next; - } - SECMOD_ReleaseReadLock(lock); - - if (RootsModule) - { - PRInt32 modType; - if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType)) - { - xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName); - } - else - { - xmlsec_trace("Failed to delete \"%s\" : \n%s", - RootsModule->commonName, RootsModule->dllName); - } - SECMOD_DestroyModule(RootsModule); - RootsModule = 0; - } -} - -::rtl::OString getMozillaCurrentProfile( const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF ) -{ - ::rtl::OString sResult; - // first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER" - char* pEnv = getenv( "MOZILLA_CERTIFICATE_FOLDER" ); - if ( pEnv ) - { - sResult = ::rtl::OString( pEnv ); - RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", sResult.getStr() ); - } - else - { - mozilla::MozillaProductType productTypes[4] = { - mozilla::MozillaProductType_Thunderbird, - mozilla::MozillaProductType_Mozilla, - mozilla::MozillaProductType_Firefox, - mozilla::MozillaProductType_Default }; - int nProduct = 4; - - uno::Reference<uno::XInterface> xInstance = rxMSF->createInstance( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) ); - OSL_ENSURE( xInstance.is(), "failed to create instance" ); - - uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap - = uno::Reference<mozilla::XMozillaBootstrap>(xInstance,uno::UNO_QUERY); - OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" ); - - if (xMozillaBootstrap.is()) - { - for (int i=0; i<nProduct; i++) - { - ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]); - - if (profile != NULL && profile.getLength()>0) - { - ::rtl::OUString sProfilePath = xMozillaBootstrap->getProfilePath( productTypes[i], profile ); - sResult = ::rtl::OUStringToOString( sProfilePath, osl_getThreadTextEncoding() ); - RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using Mozilla Profile: %s", sResult.getStr() ); - } - } - } - - RTL_LOGFILE_PRODUCT_TRACE( "XMLSEC: No Mozilla Profile found!" ); - } - - return sResult; -} - -//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write -//the roots certificate module (libnssckbi.so), which they use, into the -//profile. This module will then already be loaded during NSS_Init (and the -//other init functions). This fails in two cases. First, FF3 was used to create -//the profile, or possibly used that profile before, and second the profile was -//used on a different platform. -// -//Then one needs to add the roots module oneself. This should be done with -//SECMOD_LoadUserModule rather then SECMOD_AddNewModule. The latter would write -//the location of the roots module to the profile, which makes FF2 and TB2 use -//it instead of there own module. -// -//When using SYSTEM_MOZILLA then the libnss3.so lib is typically found in -///usr/lib. This folder may, however, NOT contain the roots certificate -//module. That is, just providing the library name in SECMOD_LoadUserModule or -//SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH -//contains an FF or TB installation. -//ATTENTION: DO NOT call this function directly instead use initNSS -//return true - whole initialization was successful -//param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite -//was successful and therefor NSS_Shutdown should be called when terminating. -bool nsscrypto_initialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF, bool & out_nss_init ) -{ - bool return_value = true; - - // this method must be called only once, no need for additional lock - rtl::OString sCertDir; - if ( xMSF.is() ) - sCertDir = getMozillaCurrentProfile( xMSF ); - - 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; - -#if defined SYSTEM_MOZILLA - if (!SECMOD_HasRootCerts()) - { -#endif - deleteRootsModule(); - -#if defined SYSTEM_MOZILLA - OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("libnssckbi"SAL_DLLEXTENSION)); -#else - OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("${OOO_BASE_DIR}/program/libnssckbi"SAL_DLLEXTENSION)); -#endif - ::rtl::Bootstrap::expandMacros(rootModule); - - OUString rootModulePath; - if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath)) - { - ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding()); - ::rtl::OStringBuffer pkcs11moduleSpec; - pkcs11moduleSpec.append("name=\""); - pkcs11moduleSpec.append(ROOT_CERTS); - pkcs11moduleSpec.append("\" library=\""); - pkcs11moduleSpec.append(ospath.getStr()); - pkcs11moduleSpec.append("\""); - - SECMODModule * RootsModule = - SECMOD_LoadUserModule( - const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()), - 0, // no parent - PR_FALSE); // do not recurse - - if (RootsModule) - { - - bool found = RootsModule->loaded; - - SECMOD_DestroyModule(RootsModule); - RootsModule = 0; - if (found) - xmlsec_trace("Added new root certificate module " - "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); - else - { - xmlsec_trace("FAILED to load the new root certificate module " - "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); - return_value = false; - } - } - else - { - xmlsec_trace("FAILED to add new root certifice module: " - "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); - return_value = false; - - } - } - else - { - xmlsec_trace("Adding new root certificate module failed."); - return_value = false; - } -#if SYSTEM_MOZILLA - } -#endif - - return return_value; -} - - -// must be extern "C" because we pass the function pointer to atexit -extern "C" void nsscrypto_finalize() -{ - SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS); - - if (RootsModule) - { - - if (SECSuccess == SECMOD_UnloadUserModule(RootsModule)) - { - xmlsec_trace("Unloaded module \""ROOT_CERTS"\"."); - } - else - { - xmlsec_trace("Failed unloadeding module \""ROOT_CERTS"\"."); - } - SECMOD_DestroyModule(RootsModule); - } - else - { - xmlsec_trace("Unloading module \""ROOT_CERTS - "\" failed because it was not found."); - } - PK11_LogoutAll(); - NSS_Shutdown(); -} -} // namespace - SEInitializer_NssImpl::SEInitializer_NssImpl( - const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF) - :mxMSF( rxMSF ) + const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF ) + : ONSSInitialize( rxMSF ) { } @@ -414,7 +101,7 @@ cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL { CERTCertDBHandle *pCertHandle = NULL ; - if( ! *initNSS( mxMSF ) ) + if( !initNSS( mxMSF ) ) return NULL; pCertHandle = CERT_GetDefaultCertDB() ; @@ -450,74 +137,6 @@ cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL } } -css::uno::Reference< css::xml::crypto::XDigestContext > SAL_CALL SEInitializer_NssImpl::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 SEInitializer_NssImpl::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 = -1; - 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 SEInitializer_NssImpl_getImplementationName () throw (cssu::RuntimeException) { |