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