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 
InitNSSInitialize__anonc1099bfd0111::InitNSSInitialize104cdf0e10cSrcweir     InitNSSInitialize( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF )
105cdf0e10cSrcweir     : mxMSF( xMSF )
106cdf0e10cSrcweir     {
107cdf0e10cSrcweir     }
108cdf0e10cSrcweir 
operator ()__anonc1099bfd0111::InitNSSInitialize109cdf0e10cSrcweir     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 {
operator ()__anonc1099bfd0111::GetNSSInitStaticMutex122cdf0e10cSrcweir     ::osl::Mutex* operator()()
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         static ::osl::Mutex aNSSInitMutex;
125cdf0e10cSrcweir         return &aNSSInitMutex;
126cdf0e10cSrcweir     }
127cdf0e10cSrcweir };
128cdf0e10cSrcweir 
deleteRootsModule()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 
getMozillaCurrentProfile(const css::uno::Reference<css::lang::XMultiServiceFactory> & rxMSF)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 //
2371b373359SDamjan Jovanovic //When using SYSTEM_NSS 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.
nsscrypto_initialize(const css::uno::Reference<css::lang::XMultiServiceFactory> & xMSF,bool & out_nss_init)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.");
268*cf2339f9SDamjan Jovanovic             PRInt32 errorLength = PR_GetErrorTextLength();
269*cf2339f9SDamjan Jovanovic             char *error = new char[errorLength + 1];
270*cf2339f9SDamjan Jovanovic             error[0] = '\0'; // as per https://bugzilla.mozilla.org/show_bug.cgi?id=538940
271cdf0e10cSrcweir             PR_GetErrorText(error);
272*cf2339f9SDamjan Jovanovic             if (error[0])
273cdf0e10cSrcweir                 xmlsec_trace("%s",error);
274*cf2339f9SDamjan Jovanovic             delete[] error;
275cdf0e10cSrcweir             return false ;
276cdf0e10cSrcweir         }
277cdf0e10cSrcweir     }
278cdf0e10cSrcweir     else
279cdf0e10cSrcweir     {
280cdf0e10cSrcweir         xmlsec_trace("Initializing NSS without profile.");
281cdf0e10cSrcweir         if ( NSS_NoDB_Init(NULL) != SECSuccess )
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             xmlsec_trace("Initializing NSS without profile failed.");
284*cf2339f9SDamjan Jovanovic             PRInt32 errorLength = PR_GetErrorTextLength();
285*cf2339f9SDamjan Jovanovic             char *error = new char[errorLength + 1];
286*cf2339f9SDamjan Jovanovic             error[0] = '\0';
287cdf0e10cSrcweir             PR_GetErrorText(error);
288*cf2339f9SDamjan Jovanovic             if (error[0])
289cdf0e10cSrcweir                 xmlsec_trace("%s",error);
290*cf2339f9SDamjan Jovanovic             delete[] error;
291cdf0e10cSrcweir             return false ;
292cdf0e10cSrcweir         }
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir     out_nss_init = true;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir #ifdef XMLSEC_CRYPTO_NSS
2971b373359SDamjan Jovanovic #if defined SYSTEM_NSS
298cdf0e10cSrcweir     if (!SECMOD_HasRootCerts())
299cdf0e10cSrcweir     {
300cdf0e10cSrcweir #endif
301cdf0e10cSrcweir         deleteRootsModule();
302cdf0e10cSrcweir 
30366d4592eSYuri Dario #if defined OS2
30466d4592eSYuri Dario         // YD the nss system dlls names are ending with 'k'
30566d4592eSYuri Dario         OUString rootModule(RTL_CONSTASCII_USTRINGPARAM( "nssckbik" SAL_DLLEXTENSION));
3061b373359SDamjan Jovanovic #elif defined SYSTEM_NSS
3076f51c329SHerbert Dürr         OUString rootModule(RTL_CONSTASCII_USTRINGPARAM( "libnssckbi" SAL_DLLEXTENSION));
308cdf0e10cSrcweir #else
3096f51c329SHerbert Dürr         OUString rootModule(RTL_CONSTASCII_USTRINGPARAM( "${OOO_BASE_DIR}/program/libnssckbi" SAL_DLLEXTENSION));
310cdf0e10cSrcweir #endif
311cdf0e10cSrcweir         ::rtl::Bootstrap::expandMacros(rootModule);
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         OUString rootModulePath;
314cdf0e10cSrcweir         if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath))
315cdf0e10cSrcweir         {
316cdf0e10cSrcweir             ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding());
317cdf0e10cSrcweir             ::rtl::OStringBuffer pkcs11moduleSpec;
318cdf0e10cSrcweir             pkcs11moduleSpec.append("name=\"");
319cdf0e10cSrcweir             pkcs11moduleSpec.append(ROOT_CERTS);
320cdf0e10cSrcweir             pkcs11moduleSpec.append("\" library=\"");
321cdf0e10cSrcweir             pkcs11moduleSpec.append(ospath.getStr());
322cdf0e10cSrcweir             pkcs11moduleSpec.append("\"");
323cdf0e10cSrcweir 
324cdf0e10cSrcweir             SECMODModule * RootsModule =
325cdf0e10cSrcweir                 SECMOD_LoadUserModule(
326cdf0e10cSrcweir                     const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()),
327cdf0e10cSrcweir                     0, // no parent
328cdf0e10cSrcweir                     PR_FALSE); // do not recurse
329cdf0e10cSrcweir 
330cdf0e10cSrcweir             if (RootsModule)
331cdf0e10cSrcweir             {
332cdf0e10cSrcweir 
333cdf0e10cSrcweir                 bool found = RootsModule->loaded;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir                 SECMOD_DestroyModule(RootsModule);
336cdf0e10cSrcweir                 RootsModule = 0;
337cdf0e10cSrcweir                 if (found)
338cdf0e10cSrcweir                     xmlsec_trace("Added new root certificate module "
3396f51c329SHerbert Dürr                               "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr());
340cdf0e10cSrcweir                 else
341cdf0e10cSrcweir                 {
342cdf0e10cSrcweir                     xmlsec_trace("FAILED to load the new root certificate module "
3436f51c329SHerbert Dürr                               "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr());
344cdf0e10cSrcweir                     return_value = false;
345cdf0e10cSrcweir                 }
346cdf0e10cSrcweir             }
347cdf0e10cSrcweir             else
348cdf0e10cSrcweir             {
349cdf0e10cSrcweir                 xmlsec_trace("FAILED to add new root certifice module: "
3506f51c329SHerbert Dürr                           "\"" ROOT_CERTS "\" contained in \n%s", ospath.getStr());
351cdf0e10cSrcweir                 return_value = false;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir             }
354cdf0e10cSrcweir         }
355cdf0e10cSrcweir         else
356cdf0e10cSrcweir         {
357cdf0e10cSrcweir             xmlsec_trace("Adding new root certificate module failed.");
358cdf0e10cSrcweir             return_value = false;
359cdf0e10cSrcweir         }
3601b373359SDamjan Jovanovic #if SYSTEM_NSS
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir #endif
363cdf0e10cSrcweir #endif
364cdf0e10cSrcweir 
365cdf0e10cSrcweir     return return_value;
366cdf0e10cSrcweir }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 
369cdf0e10cSrcweir // must be extern "C" because we pass the function pointer to atexit
nsscrypto_finalize()370cdf0e10cSrcweir extern "C" void nsscrypto_finalize()
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir     if (RootsModule)
375cdf0e10cSrcweir     {
376cdf0e10cSrcweir 
377cdf0e10cSrcweir         if (SECSuccess == SECMOD_UnloadUserModule(RootsModule))
378cdf0e10cSrcweir         {
3796f51c329SHerbert Dürr             xmlsec_trace( "Unloaded module \"" ROOT_CERTS "\".");
380cdf0e10cSrcweir         }
381cdf0e10cSrcweir         else
382cdf0e10cSrcweir         {
3836f51c329SHerbert Dürr             xmlsec_trace( "Failed unloadeding module \"" ROOT_CERTS "\".");
384cdf0e10cSrcweir         }
385cdf0e10cSrcweir         SECMOD_DestroyModule(RootsModule);
386cdf0e10cSrcweir     }
387cdf0e10cSrcweir     else
388cdf0e10cSrcweir     {
3896f51c329SHerbert Dürr         xmlsec_trace( "Unloading module \"" ROOT_CERTS
390cdf0e10cSrcweir                   "\" failed because it was not found.");
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir     PK11_LogoutAll();
393cdf0e10cSrcweir     NSS_Shutdown();
394cdf0e10cSrcweir }
395cdf0e10cSrcweir } // namespace
396cdf0e10cSrcweir 
ONSSInitializer(const css::uno::Reference<css::lang::XMultiServiceFactory> & rxMSF)397cdf0e10cSrcweir ONSSInitializer::ONSSInitializer(
398cdf0e10cSrcweir     const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF)
399cdf0e10cSrcweir     :mxMSF( rxMSF )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
~ONSSInitializer()403cdf0e10cSrcweir ONSSInitializer::~ONSSInitializer()
404cdf0e10cSrcweir {
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
initNSS(const css::uno::Reference<css::lang::XMultiServiceFactory> & xMSF)407cdf0e10cSrcweir bool ONSSInitializer::initNSS( const css::uno::Reference< css::lang::XMultiServiceFactory > &xMSF )
408cdf0e10cSrcweir {
409cdf0e10cSrcweir     return *rtl_Instance< bool, InitNSSInitialize, ::osl::MutexGuard, GetNSSInitStaticMutex >
410cdf0e10cSrcweir                 ::create( InitNSSInitialize( xMSF ), GetNSSInitStaticMutex() );
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
getDigestContext(::sal_Int32 nDigestID,const css::uno::Sequence<css::beans::NamedValue> & aParams)413cdf0e10cSrcweir css::uno::Reference< css::xml::crypto::XDigestContext > SAL_CALL ONSSInitializer::getDigestContext( ::sal_Int32 nDigestID, const css::uno::Sequence< css::beans::NamedValue >& aParams )
414cdf0e10cSrcweir     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
415cdf0e10cSrcweir {
416cdf0e10cSrcweir     SECOidTag nNSSDigestID = SEC_OID_UNKNOWN;
417cdf0e10cSrcweir     sal_Int32 nDigestLength = 0;
418cdf0e10cSrcweir     bool b1KData = false;
419cdf0e10cSrcweir     if ( nDigestID == css::xml::crypto::DigestID::SHA256
420cdf0e10cSrcweir       || nDigestID == css::xml::crypto::DigestID::SHA256_1K )
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         nNSSDigestID = SEC_OID_SHA256;
423cdf0e10cSrcweir         nDigestLength = 32;
424cdf0e10cSrcweir         b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA256_1K );
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir     else if ( nDigestID == css::xml::crypto::DigestID::SHA1
427cdf0e10cSrcweir            || nDigestID == css::xml::crypto::DigestID::SHA1_1K )
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         nNSSDigestID = SEC_OID_SHA1;
430cdf0e10cSrcweir         nDigestLength = 20;
431cdf0e10cSrcweir         b1KData = ( nDigestID == css::xml::crypto::DigestID::SHA1_1K );
432cdf0e10cSrcweir     }
433cdf0e10cSrcweir     else
434cdf0e10cSrcweir         throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected digest requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 );
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     if ( aParams.getLength() )
437cdf0e10cSrcweir         throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for digest creation." ) ), css::uno::Reference< css::uno::XInterface >(), 2 );
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     css::uno::Reference< css::xml::crypto::XDigestContext > xResult;
440cdf0e10cSrcweir     if( initNSS( mxMSF ) )
441cdf0e10cSrcweir     {
442cdf0e10cSrcweir         PK11Context* pContext = PK11_CreateDigestContext( nNSSDigestID );
443cdf0e10cSrcweir         if ( pContext && PK11_DigestBegin( pContext ) == SECSuccess )
444cdf0e10cSrcweir             xResult = new ODigestContext( pContext, nDigestLength, b1KData );
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     return xResult;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
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)450cdf0e10cSrcweir 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 )
451cdf0e10cSrcweir     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
452cdf0e10cSrcweir {
453cdf0e10cSrcweir     CK_MECHANISM_TYPE nNSSCipherID = 0;
454cdf0e10cSrcweir     bool bW3CPadding = false;
455cdf0e10cSrcweir     if ( nCipherID == css::xml::crypto::CipherID::AES_CBC_W3C_PADDING )
456cdf0e10cSrcweir     {
457cdf0e10cSrcweir         nNSSCipherID = CKM_AES_CBC;
458cdf0e10cSrcweir         bW3CPadding = true;
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         if ( aKey.getLength() != 16 && aKey.getLength() != 24 && aKey.getLength() != 32 )
461cdf0e10cSrcweir             throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected key length." ) ), css::uno::Reference< css::uno::XInterface >(), 2 );
462cdf0e10cSrcweir 
463cdf0e10cSrcweir         if ( aParams.getLength() )
464cdf0e10cSrcweir             throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments provided for cipher creation." ) ), css::uno::Reference< css::uno::XInterface >(), 5 );
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir     else
467cdf0e10cSrcweir         throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected cipher requested." ) ), css::uno::Reference< css::uno::XInterface >(), 1 );
468cdf0e10cSrcweir 
469cdf0e10cSrcweir     css::uno::Reference< css::xml::crypto::XCipherContext > xResult;
470cdf0e10cSrcweir     if( initNSS( mxMSF ) )
471cdf0e10cSrcweir     {
472cdf0e10cSrcweir         if ( aInitializationVector.getLength() != PK11_GetIVLength( nNSSCipherID ) )
473cdf0e10cSrcweir             throw css::lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected length of initialization vector." ) ), css::uno::Reference< css::uno::XInterface >(), 3 );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir         xResult = OCipherContext::Create( nNSSCipherID, aKey, aInitializationVector, bEncryption, bW3CPadding );
476cdf0e10cSrcweir     }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir     return xResult;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir 
ONSSInitializer_getImplementationName()481cdf0e10cSrcweir rtl::OUString ONSSInitializer_getImplementationName ()
482cdf0e10cSrcweir     throw (cssu::RuntimeException)
483cdf0e10cSrcweir {
484cdf0e10cSrcweir 
485cdf0e10cSrcweir     return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
ONSSInitializer_supportsService(const rtl::OUString & ServiceName)488cdf0e10cSrcweir sal_Bool SAL_CALL ONSSInitializer_supportsService( const rtl::OUString& ServiceName )
489cdf0e10cSrcweir     throw (cssu::RuntimeException)
490cdf0e10cSrcweir {
491cdf0e10cSrcweir     return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( NSS_SERVICE_NAME ));
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
ONSSInitializer_getSupportedServiceNames()494cdf0e10cSrcweir cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer_getSupportedServiceNames(  )
495cdf0e10cSrcweir     throw (cssu::RuntimeException)
496cdf0e10cSrcweir {
497cdf0e10cSrcweir     cssu::Sequence < rtl::OUString > aRet(1);
498cdf0e10cSrcweir     rtl::OUString* pArray = aRet.getArray();
499cdf0e10cSrcweir     pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( NSS_SERVICE_NAME ) );
500cdf0e10cSrcweir     return aRet;
501cdf0e10cSrcweir }
502cdf0e10cSrcweir 
ONSSInitializer_createInstance(const cssu::Reference<cssl::XMultiServiceFactory> & rSMgr)503cdf0e10cSrcweir cssu::Reference< cssu::XInterface > SAL_CALL ONSSInitializer_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr)
504cdf0e10cSrcweir     throw( cssu::Exception )
505cdf0e10cSrcweir {
506cdf0e10cSrcweir     return (cppu::OWeakObject*) new ONSSInitializer( rSMgr );
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
509cdf0e10cSrcweir /* XServiceInfo */
getImplementationName()510cdf0e10cSrcweir rtl::OUString SAL_CALL ONSSInitializer::getImplementationName()
511cdf0e10cSrcweir     throw (cssu::RuntimeException)
512cdf0e10cSrcweir {
513cdf0e10cSrcweir     return ONSSInitializer_getImplementationName();
514cdf0e10cSrcweir }
supportsService(const rtl::OUString & rServiceName)515cdf0e10cSrcweir sal_Bool SAL_CALL ONSSInitializer::supportsService( const rtl::OUString& rServiceName )
516cdf0e10cSrcweir     throw (cssu::RuntimeException)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir     return ONSSInitializer_supportsService( rServiceName );
519cdf0e10cSrcweir }
getSupportedServiceNames()520cdf0e10cSrcweir cssu::Sequence< rtl::OUString > SAL_CALL ONSSInitializer::getSupportedServiceNames(  )
521cdf0e10cSrcweir     throw (cssu::RuntimeException)
522cdf0e10cSrcweir {
523cdf0e10cSrcweir     return ONSSInitializer_getSupportedServiceNames();
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
526