1d0626817SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3d0626817SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4d0626817SAndrew Rist * or more contributor license agreements. See the NOTICE file 5d0626817SAndrew Rist * distributed with this work for additional information 6d0626817SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7d0626817SAndrew Rist * to you under the Apache License, Version 2.0 (the 8d0626817SAndrew Rist * "License"); you may not use this file except in compliance 9d0626817SAndrew Rist * with the License. You may obtain a copy of the License at 10d0626817SAndrew Rist * 11d0626817SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12d0626817SAndrew Rist * 13d0626817SAndrew Rist * Unless required by applicable law or agreed to in writing, 14d0626817SAndrew Rist * software distributed under the License is distributed on an 15d0626817SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16d0626817SAndrew Rist * KIND, either express or implied. See the License for the 17d0626817SAndrew Rist * specific language governing permissions and limitations 18d0626817SAndrew Rist * under the License. 19d0626817SAndrew Rist * 20d0626817SAndrew Rist *************************************************************/ 21d0626817SAndrew Rist 22d0626817SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir /* 28cdf0e10cSrcweir * Turn off DEBUG Assertions 29cdf0e10cSrcweir */ 30cdf0e10cSrcweir #ifdef _DEBUG 31cdf0e10cSrcweir #define _DEBUG_WAS_DEFINED _DEBUG 32cdf0e10cSrcweir #undef _DEBUG 33cdf0e10cSrcweir #else 34cdf0e10cSrcweir #undef _DEBUG_WAS_DEFINED 35cdf0e10cSrcweir #endif 36cdf0e10cSrcweir 37cdf0e10cSrcweir /* 38cdf0e10cSrcweir * and turn off the additional virtual methods which are part of some interfaces when compiled 39cdf0e10cSrcweir * with debug 40cdf0e10cSrcweir */ 41cdf0e10cSrcweir #ifdef DEBUG 42cdf0e10cSrcweir #define DEBUG_WAS_DEFINED DEBUG 43cdf0e10cSrcweir #undef DEBUG 44cdf0e10cSrcweir #else 45cdf0e10cSrcweir #undef DEBUG_WAS_DEFINED 46cdf0e10cSrcweir #endif 47cdf0e10cSrcweir 48cdf0e10cSrcweir 49cdf0e10cSrcweir #include <com/sun/star/mozilla/XMozillaBootstrap.hpp> 50cdf0e10cSrcweir #include <com/sun/star/xml/crypto/DigestID.hpp> 51cdf0e10cSrcweir #include <com/sun/star/xml/crypto/CipherID.hpp> 52cdf0e10cSrcweir 53cdf0e10cSrcweir #include <sal/types.h> 54cdf0e10cSrcweir #include <rtl/instance.hxx> 55cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 56cdf0e10cSrcweir #include <rtl/string.hxx> 57cdf0e10cSrcweir #include <rtl/strbuf.hxx> 58cdf0e10cSrcweir #include <osl/file.hxx> 59cdf0e10cSrcweir #include <osl/thread.h> 60cdf0e10cSrcweir #include <tools/debug.hxx> 61cdf0e10cSrcweir #include <rtl/logfile.hxx> 62cdf0e10cSrcweir 63cdf0e10cSrcweir #include "seinitializer_nssimpl.hxx" 64cdf0e10cSrcweir #include "../diagnose.hxx" 65cdf0e10cSrcweir 66cdf0e10cSrcweir #include "securityenvironment_nssimpl.hxx" 67cdf0e10cSrcweir #include "digestcontext.hxx" 68cdf0e10cSrcweir #include "ciphercontext.hxx" 69cdf0e10cSrcweir 70cdf0e10cSrcweir #include <nspr.h> 71cdf0e10cSrcweir #include <cert.h> 72cdf0e10cSrcweir #include <nss.h> 73cdf0e10cSrcweir #include <pk11pub.h> 74cdf0e10cSrcweir #include <secmod.h> 75cdf0e10cSrcweir #include <nssckbi.h> 76cdf0e10cSrcweir 77cdf0e10cSrcweir 78cdf0e10cSrcweir namespace css = ::com::sun::star; 79cdf0e10cSrcweir namespace cssu = css::uno; 80cdf0e10cSrcweir namespace cssl = css::lang; 81cdf0e10cSrcweir namespace cssxc = css::xml::crypto; 82cdf0e10cSrcweir 83cdf0e10cSrcweir using namespace xmlsecurity; 84cdf0e10cSrcweir using namespace com::sun::star; 85cdf0e10cSrcweir using ::rtl::OUString; 86cdf0e10cSrcweir using ::rtl::OString; 87cdf0e10cSrcweir 88cdf0e10cSrcweir #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.NSSInitializer_NssImpl" 89cdf0e10cSrcweir 90ff3f4ebcSOliver-Rainer Wittmann #define ROOT_CERTS "Root Certs for Apache OpenOffice" 91cdf0e10cSrcweir 92cdf0e10cSrcweir extern "C" void nsscrypto_finalize(); 93cdf0e10cSrcweir 94cdf0e10cSrcweir 95cdf0e10cSrcweir namespace 96cdf0e10cSrcweir { 97cdf0e10cSrcweir 98cdf0e10cSrcweir bool nsscrypto_initialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF, bool & out_nss_init ); 99cdf0e10cSrcweir 100cdf0e10cSrcweir struct InitNSSInitialize 101cdf0e10cSrcweir { 102cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF; 103cdf0e10cSrcweir 104cdf0e10cSrcweir InitNSSInitialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF ) 105cdf0e10cSrcweir : mxMSF( xMSF ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir bool * operator()() 110cdf0e10cSrcweir { 111cdf0e10cSrcweir static bool bInitialized = false; 112cdf0e10cSrcweir bool bNSSInit = false; 113cdf0e10cSrcweir bInitialized = nsscrypto_initialize( mxMSF, bNSSInit ); 114cdf0e10cSrcweir if (bNSSInit) 115cdf0e10cSrcweir atexit(nsscrypto_finalize ); 116cdf0e10cSrcweir return & bInitialized; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir }; 119cdf0e10cSrcweir 120cdf0e10cSrcweir struct GetNSSInitStaticMutex 121cdf0e10cSrcweir { 122cdf0e10cSrcweir ::osl::Mutex* operator()() 123cdf0e10cSrcweir { 124cdf0e10cSrcweir static ::osl::Mutex aNSSInitMutex; 125cdf0e10cSrcweir return &aNSSInitMutex; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir }; 128cdf0e10cSrcweir 129cdf0e10cSrcweir void deleteRootsModule() 130cdf0e10cSrcweir { 131cdf0e10cSrcweir SECMODModule *RootsModule = 0; 132cdf0e10cSrcweir SECMODModuleList *list = SECMOD_GetDefaultModuleList(); 133cdf0e10cSrcweir SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); 134cdf0e10cSrcweir SECMOD_GetReadLock(lock); 135cdf0e10cSrcweir 136cdf0e10cSrcweir while (!RootsModule && list) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir SECMODModule *module = list->module; 139cdf0e10cSrcweir 140cdf0e10cSrcweir for (int i=0; i < module->slotCount; i++) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir PK11SlotInfo *slot = module->slots[i]; 143cdf0e10cSrcweir if (PK11_IsPresent(slot)) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir if (PK11_HasRootCerts(slot)) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir xmlsec_trace("The root certifificates module \"%s" 148cdf0e10cSrcweir "\" is already loaded: \n%s", 149cdf0e10cSrcweir module->commonName, module->dllName); 150cdf0e10cSrcweir 151cdf0e10cSrcweir RootsModule = SECMOD_ReferenceModule(module); 152cdf0e10cSrcweir break; 153cdf0e10cSrcweir } 154cdf0e10cSrcweir } 155cdf0e10cSrcweir } 156cdf0e10cSrcweir list = list->next; 157cdf0e10cSrcweir } 158cdf0e10cSrcweir SECMOD_ReleaseReadLock(lock); 159cdf0e10cSrcweir 160cdf0e10cSrcweir if (RootsModule) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir PRInt32 modType; 163cdf0e10cSrcweir if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType)) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName); 166cdf0e10cSrcweir } 167cdf0e10cSrcweir else 168cdf0e10cSrcweir { 169cdf0e10cSrcweir xmlsec_trace("Failed to delete \"%s\" : \n%s", 170cdf0e10cSrcweir RootsModule->commonName, RootsModule->dllName); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir SECMOD_DestroyModule(RootsModule); 173cdf0e10cSrcweir RootsModule = 0; 174cdf0e10cSrcweir } 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir ::rtl::OString getMozillaCurrentProfile( const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF ) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir ::rtl::OString sResult; 180cdf0e10cSrcweir // first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER" 181cdf0e10cSrcweir char* pEnv = getenv( "MOZILLA_CERTIFICATE_FOLDER" ); 182cdf0e10cSrcweir if ( pEnv ) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir sResult = ::rtl::OString( pEnv ); 185cdf0e10cSrcweir RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", sResult.getStr() ); 186cdf0e10cSrcweir } 187cdf0e10cSrcweir else 188cdf0e10cSrcweir { 189cdf0e10cSrcweir mozilla::MozillaProductType productTypes[4] = { 190cdf0e10cSrcweir mozilla::MozillaProductType_Thunderbird, 191cdf0e10cSrcweir mozilla::MozillaProductType_Mozilla, 192cdf0e10cSrcweir mozilla::MozillaProductType_Firefox, 193cdf0e10cSrcweir mozilla::MozillaProductType_Default }; 194cdf0e10cSrcweir int nProduct = 4; 195cdf0e10cSrcweir 196cdf0e10cSrcweir uno::Reference<uno::XInterface> xInstance = rxMSF->createInstance( 197cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) ); 198cdf0e10cSrcweir OSL_ENSURE( xInstance.is(), "failed to create instance" ); 199cdf0e10cSrcweir 200cdf0e10cSrcweir uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap 201cdf0e10cSrcweir = uno::Reference<mozilla::XMozillaBootstrap>(xInstance,uno::UNO_QUERY); 202cdf0e10cSrcweir OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" ); 203cdf0e10cSrcweir 204cdf0e10cSrcweir if (xMozillaBootstrap.is()) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir for (int i=0; i<nProduct; i++) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]); 209cdf0e10cSrcweir 210cdf0e10cSrcweir if (profile != NULL && profile.getLength()>0) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir ::rtl::OUString sProfilePath = xMozillaBootstrap->getProfilePath( productTypes[i], profile ); 213cdf0e10cSrcweir sResult = ::rtl::OUStringToOString( sProfilePath, osl_getThreadTextEncoding() ); 214cdf0e10cSrcweir RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using Mozilla Profile: %s", sResult.getStr() ); 215cdf0e10cSrcweir } 216cdf0e10cSrcweir } 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir RTL_LOGFILE_PRODUCT_TRACE( "XMLSEC: No Mozilla Profile found!" ); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir return sResult; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir //Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write 226cdf0e10cSrcweir //the roots certificate module (libnssckbi.so), which they use, into the 227cdf0e10cSrcweir //profile. This module will then already be loaded during NSS_Init (and the 228cdf0e10cSrcweir //other init functions). This fails in two cases. First, FF3 was used to create 229cdf0e10cSrcweir //the profile, or possibly used that profile before, and second the profile was 230cdf0e10cSrcweir //used on a different platform. 231cdf0e10cSrcweir // 232cdf0e10cSrcweir //Then one needs to add the roots module oneself. This should be done with 233cdf0e10cSrcweir //SECMOD_LoadUserModule rather then SECMOD_AddNewModule. The latter would write 234cdf0e10cSrcweir //the location of the roots module to the profile, which makes FF2 and TB2 use 235cdf0e10cSrcweir //it instead of there own module. 236cdf0e10cSrcweir // 237cdf0e10cSrcweir //When using SYSTEM_MOZILLA then the libnss3.so lib is typically found in 238cdf0e10cSrcweir ///usr/lib. This folder may, however, NOT contain the roots certificate 239cdf0e10cSrcweir //module. That is, just providing the library name in SECMOD_LoadUserModule or 240cdf0e10cSrcweir //SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH 241cdf0e10cSrcweir //contains an FF or TB installation. 242cdf0e10cSrcweir //ATTENTION: DO NOT call this function directly instead use initNSS 243cdf0e10cSrcweir //return true - whole initialization was successful 244cdf0e10cSrcweir //param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite 245cdf0e10cSrcweir //was successful and therefor NSS_Shutdown should be called when terminating. 246cdf0e10cSrcweir bool nsscrypto_initialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF, bool & out_nss_init ) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir bool return_value = true; 249cdf0e10cSrcweir 250cdf0e10cSrcweir // this method must be called only once, no need for additional lock 251cdf0e10cSrcweir rtl::OString sCertDir; 252cdf0e10cSrcweir 253cdf0e10cSrcweir (void) xMSF; 254cdf0e10cSrcweir #ifdef XMLSEC_CRYPTO_NSS 255cdf0e10cSrcweir if ( xMSF.is() ) 256cdf0e10cSrcweir sCertDir = getMozillaCurrentProfile( xMSF ); 257cdf0e10cSrcweir #endif 258cdf0e10cSrcweir xmlsec_trace( "Using profile: %s", sCertDir.getStr() ); 259cdf0e10cSrcweir 260cdf0e10cSrcweir PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ; 261cdf0e10cSrcweir 262cdf0e10cSrcweir // there might be no profile 263cdf0e10cSrcweir if ( sCertDir.getLength() > 0 ) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir if( NSS_InitReadWrite( sCertDir.getStr() ) != SECSuccess ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir xmlsec_trace("Initializing NSS with profile failed."); 268cdf0e10cSrcweir char * error = NULL; 269cdf0e10cSrcweir 270cdf0e10cSrcweir PR_GetErrorText(error); 271cdf0e10cSrcweir if (error) 272cdf0e10cSrcweir xmlsec_trace("%s",error); 273cdf0e10cSrcweir return false ; 274cdf0e10cSrcweir } 275cdf0e10cSrcweir } 276cdf0e10cSrcweir else 277cdf0e10cSrcweir { 278cdf0e10cSrcweir xmlsec_trace("Initializing NSS without profile."); 279cdf0e10cSrcweir if ( NSS_NoDB_Init(NULL) != SECSuccess ) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir xmlsec_trace("Initializing NSS without profile failed."); 282cdf0e10cSrcweir char * error = NULL; 283cdf0e10cSrcweir PR_GetErrorText(error); 284cdf0e10cSrcweir if (error) 285cdf0e10cSrcweir xmlsec_trace("%s",error); 286cdf0e10cSrcweir return false ; 287cdf0e10cSrcweir } 288cdf0e10cSrcweir } 289cdf0e10cSrcweir out_nss_init = true; 290cdf0e10cSrcweir 291cdf0e10cSrcweir #ifdef XMLSEC_CRYPTO_NSS 292cdf0e10cSrcweir #if defined SYSTEM_MOZILLA 293cdf0e10cSrcweir if (!SECMOD_HasRootCerts()) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir #endif 296cdf0e10cSrcweir deleteRootsModule(); 297cdf0e10cSrcweir 298cdf0e10cSrcweir #if defined SYSTEM_MOZILLA 299*6f51c329SHerbert Dürr OUString rootModule(RTL_CONSTASCII_USTRINGPARAM( "libnssckbi" SAL_DLLEXTENSION)); 300cdf0e10cSrcweir #else 301*6f51c329SHerbert Dürr OUString rootModule(RTL_CONSTASCII_USTRINGPARAM( "${OOO_BASE_DIR}/program/libnssckbi" SAL_DLLEXTENSION)); 302cdf0e10cSrcweir #endif 303cdf0e10cSrcweir ::rtl::Bootstrap::expandMacros(rootModule); 304cdf0e10cSrcweir 305cdf0e10cSrcweir OUString rootModulePath; 306cdf0e10cSrcweir if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath)) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding()); 309cdf0e10cSrcweir ::rtl::OStringBuffer pkcs11moduleSpec; 310cdf0e10cSrcweir pkcs11moduleSpec.append("name=\""); 311cdf0e10cSrcweir pkcs11moduleSpec.append(ROOT_CERTS); 312cdf0e10cSrcweir pkcs11moduleSpec.append("\" library=\""); 313cdf0e10cSrcweir pkcs11moduleSpec.append(ospath.getStr()); 314cdf0e10cSrcweir pkcs11moduleSpec.append("\""); 315cdf0e10cSrcweir 316cdf0e10cSrcweir SECMODModule * RootsModule = 317cdf0e10cSrcweir SECMOD_LoadUserModule( 318cdf0e10cSrcweir const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()), 319cdf0e10cSrcweir 0, // no parent 320cdf0e10cSrcweir PR_FALSE); // do not recurse 321cdf0e10cSrcweir 322cdf0e10cSrcweir if (RootsModule) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir 325cdf0e10cSrcweir bool found = RootsModule->loaded; 326cdf0e10cSrcweir 327cdf0e10cSrcweir SECMOD_DestroyModule(RootsModule); 328cdf0e10cSrcweir RootsModule = 0; 329cdf0e10cSrcweir if (found) 330cdf0e10cSrcweir xmlsec_trace("Added new root certificate module " 331*6f51c329SHerbert Dürr "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr()); 332cdf0e10cSrcweir else 333cdf0e10cSrcweir { 334cdf0e10cSrcweir xmlsec_trace("FAILED to load the new root certificate module " 335*6f51c329SHerbert Dürr "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr()); 336cdf0e10cSrcweir return_value = false; 337cdf0e10cSrcweir } 338cdf0e10cSrcweir } 339cdf0e10cSrcweir else 340cdf0e10cSrcweir { 341cdf0e10cSrcweir xmlsec_trace("FAILED to add new root certifice module: " 342*6f51c329SHerbert Dürr "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr()); 343cdf0e10cSrcweir return_value = false; 344cdf0e10cSrcweir 345cdf0e10cSrcweir } 346cdf0e10cSrcweir } 347cdf0e10cSrcweir else 348cdf0e10cSrcweir { 349cdf0e10cSrcweir xmlsec_trace("Adding new root certificate module failed."); 350cdf0e10cSrcweir return_value = false; 351cdf0e10cSrcweir } 352cdf0e10cSrcweir #if SYSTEM_MOZILLA 353cdf0e10cSrcweir } 354cdf0e10cSrcweir #endif 355cdf0e10cSrcweir #endif 356cdf0e10cSrcweir 357cdf0e10cSrcweir return return_value; 358cdf0e10cSrcweir } 359cdf0e10cSrcweir 360cdf0e10cSrcweir 361cdf0e10cSrcweir // must be extern "C" because we pass the function pointer to atexit 362cdf0e10cSrcweir extern "C" void nsscrypto_finalize() 363cdf0e10cSrcweir { 364cdf0e10cSrcweir SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS); 365cdf0e10cSrcweir 366cdf0e10cSrcweir if (RootsModule) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir 369cdf0e10cSrcweir if (SECSuccess == SECMOD_UnloadUserModule(RootsModule)) 370cdf0e10cSrcweir { 371*6f51c329SHerbert Dürr xmlsec_trace( "Unloaded module \"" ROOT_CERTS "\"."); 372cdf0e10cSrcweir } 373cdf0e10cSrcweir else 374cdf0e10cSrcweir { 375*6f51c329SHerbert Dürr xmlsec_trace( "Failed unloadeding module \"" ROOT_CERTS "\"."); 376cdf0e10cSrcweir } 377cdf0e10cSrcweir SECMOD_DestroyModule(RootsModule); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir else 380cdf0e10cSrcweir { 381*6f51c329SHerbert Dürr xmlsec_trace( "Unloading module \"" ROOT_CERTS 382cdf0e10cSrcweir "\" failed because it was not found."); 383cdf0e10cSrcweir } 384cdf0e10cSrcweir PK11_LogoutAll(); 385cdf0e10cSrcweir NSS_Shutdown(); 386cdf0e10cSrcweir } 387cdf0e10cSrcweir } // namespace 388cdf0e10cSrcweir 389cdf0e10cSrcweir ONSSInitializer::ONSSInitializer( 390cdf0e10cSrcweir const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF) 391cdf0e10cSrcweir :mxMSF( rxMSF ) 392cdf0e10cSrcweir { 393cdf0e10cSrcweir } 394cdf0e10cSrcweir 395cdf0e10cSrcweir ONSSInitializer::~ONSSInitializer() 396cdf0e10cSrcweir { 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir bool ONSSInitializer::initNSS( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF ) 400cdf0e10cSrcweir { 401cdf0e10cSrcweir return *rtl_Instance< bool, InitNSSInitialize, ::osl::MutexGuard, GetNSSInitStaticMutex > 402cdf0e10cSrcweir ::create( InitNSSInitialize( xMSF ), GetNSSInitStaticMutex() ); 403cdf0e10cSrcweir } 404cdf0e10cSrcweir 405cdf0e10cSrcweir css::uno::Reference< css::xml::crypto::XDigestContext > SAL_CALL ONSSInitializer::getDigestContext( ::sal_Int32 nDigestID, const css::uno::Sequence< css::beans::NamedValue >& aParams ) 406cdf0e10cSrcweir throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir SECOidTag nNSSDigestID = SEC_OID_UNKNOWN; 409cdf0e10cSrcweir sal_Int32 nDigestLength = 0; 410cdf0e10cSrcweir bool b1KData = false; 411cdf0e10cSrcweir if ( nDigestID == css::xml::crypto::DigestID::SHA256 412cdf0e10cSrcweir || nDigestID == css::xml::crypto::DigestID::SHA256_1K ) 413cdf0e10cSrcweir { 414cdf0e10cSrcweir nNSSDigestID = SEC_OID_SHA256; 415cdf0e10cSrcweir nDigestLength = 32; 416cdf0e10cSrcweir b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA256_1K ); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir else if ( nDigestID == css::xml::crypto::DigestID::SHA1 419cdf0e10cSrcweir || nDigestID == css::xml::crypto::DigestID::SHA1_1K ) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir nNSSDigestID = SEC_OID_SHA1; 422cdf0e10cSrcweir nDigestLength = 20; 423cdf0e10cSrcweir b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA1_1K ); 424cdf0e10cSrcweir } 425cdf0e10cSrcweir else 426cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected digest requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 ); 427cdf0e10cSrcweir 428cdf0e10cSrcweir if ( aParams.getLength() ) 429cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for digest creation." ) ), css::uno::Reference< css::uno::XInterface >(), 2 ); 430cdf0e10cSrcweir 431cdf0e10cSrcweir css::uno::Reference< css::xml::crypto::XDigestContext > xResult; 432cdf0e10cSrcweir if( initNSS( mxMSF ) ) 433cdf0e10cSrcweir { 434cdf0e10cSrcweir PK11Context* pContext = PK11_CreateDigestContext( nNSSDigestID ); 435cdf0e10cSrcweir if ( pContext && PK11_DigestBegin( pContext ) == SECSuccess ) 436cdf0e10cSrcweir xResult = new ODigestContext( pContext, nDigestLength, b1KData ); 437cdf0e10cSrcweir } 438cdf0e10cSrcweir 439cdf0e10cSrcweir return xResult; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir 442cdf0e10cSrcweir 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 ) 443cdf0e10cSrcweir throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir CK_MECHANISM_TYPE nNSSCipherID = 0; 446cdf0e10cSrcweir bool bW3CPadding = false; 447cdf0e10cSrcweir if ( nCipherID == css::xml::crypto::CipherID::AES_CBC_W3C_PADDING ) 448cdf0e10cSrcweir { 449cdf0e10cSrcweir nNSSCipherID = CKM_AES_CBC; 450cdf0e10cSrcweir bW3CPadding = true; 451cdf0e10cSrcweir 452cdf0e10cSrcweir if ( aKey.getLength() != 16 && aKey.getLength() != 24 && aKey.getLength() != 32 ) 453cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected key length." ) ), css::uno::Reference< css::uno::XInterface >(), 2 ); 454cdf0e10cSrcweir 455cdf0e10cSrcweir if ( aParams.getLength() ) 456cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for cipher creation." ) ), css::uno::Reference< css::uno::XInterface >(), 5 ); 457cdf0e10cSrcweir } 458cdf0e10cSrcweir else 459cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected cipher requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 ); 460cdf0e10cSrcweir 461cdf0e10cSrcweir css::uno::Reference< css::xml::crypto::XCipherContext > xResult; 462cdf0e10cSrcweir if( initNSS( mxMSF ) ) 463cdf0e10cSrcweir { 464cdf0e10cSrcweir if ( aInitializationVector.getLength() != PK11_GetIVLength( nNSSCipherID ) ) 465cdf0e10cSrcweir throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected length of initialization vector." ) ), css::uno::Reference< css::uno::XInterface >(), 3 ); 466cdf0e10cSrcweir 467cdf0e10cSrcweir xResult = OCipherContext::Create( nNSSCipherID, aKey, aInitializationVector, bEncryption, bW3CPadding ); 468cdf0e10cSrcweir } 469cdf0e10cSrcweir 470cdf0e10cSrcweir return xResult; 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir rtl::OUString ONSSInitializer_getImplementationName () 474cdf0e10cSrcweir throw (cssu::RuntimeException) 475cdf0e10cSrcweir { 476cdf0e10cSrcweir 477cdf0e10cSrcweir return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); 478cdf0e10cSrcweir } 479cdf0e10cSrcweir 480cdf0e10cSrcweir sal_Bool SAL_CALL ONSSInitializer_supportsService( const rtl::OUString& ServiceName ) 481cdf0e10cSrcweir throw (cssu::RuntimeException) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( NSS_SERVICE_NAME )); 484cdf0e10cSrcweir } 485cdf0e10cSrcweir 486cdf0e10cSrcweir cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer_getSupportedServiceNames( ) 487cdf0e10cSrcweir throw (cssu::RuntimeException) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir cssu::Sequence < rtl::OUString > aRet(1); 490cdf0e10cSrcweir rtl::OUString* pArray = aRet.getArray(); 491cdf0e10cSrcweir pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( NSS_SERVICE_NAME ) ); 492cdf0e10cSrcweir return aRet; 493cdf0e10cSrcweir } 494cdf0e10cSrcweir 495cdf0e10cSrcweir cssu::Reference< cssu::XInterface > SAL_CALL ONSSInitializer_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr) 496cdf0e10cSrcweir throw( cssu::Exception ) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir return (cppu::OWeakObject*) new ONSSInitializer( rSMgr ); 499cdf0e10cSrcweir } 500cdf0e10cSrcweir 501cdf0e10cSrcweir /* XServiceInfo */ 502cdf0e10cSrcweir rtl::OUString SAL_CALL ONSSInitializer::getImplementationName() 503cdf0e10cSrcweir throw (cssu::RuntimeException) 504cdf0e10cSrcweir { 505cdf0e10cSrcweir return ONSSInitializer_getImplementationName(); 506cdf0e10cSrcweir } 507cdf0e10cSrcweir sal_Bool SAL_CALL ONSSInitializer::supportsService( const rtl::OUString& rServiceName ) 508cdf0e10cSrcweir throw (cssu::RuntimeException) 509cdf0e10cSrcweir { 510cdf0e10cSrcweir return ONSSInitializer_supportsService( rServiceName ); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer::getSupportedServiceNames( ) 513cdf0e10cSrcweir throw (cssu::RuntimeException) 514cdf0e10cSrcweir { 515cdf0e10cSrcweir return ONSSInitializer_getSupportedServiceNames(); 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518