Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "nssrenam.h" // rename problematic symbols
21 : : #include "cert.h"
22 : : #include "secerr.h"
23 : : #include "ocsp.h"
24 : :
25 : : #include <sal/config.h>
26 : : #include <sal/macros.h>
27 : : #include "securityenvironment_nssimpl.hxx"
28 : : #include "x509certificate_nssimpl.hxx"
29 : : #include <comphelper/servicehelper.hxx>
30 : : #include "../diagnose.hxx"
31 : :
32 : : #include <sal/types.h>
33 : : //For reasons that escape me, this is what xmlsec does when size_t is not 4
34 : : #if SAL_TYPES_SIZEOFPOINTER != 4
35 : : # define XMLSEC_NO_SIZE_T
36 : : #endif
37 : : #include <xmlsec/xmlsec.h>
38 : : #include <xmlsec/keysmngr.h>
39 : : #include <xmlsec/crypto.h>
40 : : #include <xmlsec/base64.h>
41 : : #include <xmlsec/strings.h>
42 : :
43 : : #include <rtl/ustrbuf.hxx>
44 : : #include <comphelper/processfactory.hxx>
45 : : #include <cppuhelper/servicefactory.hxx>
46 : : #include <comphelper/docpasswordrequest.hxx>
47 : : #include <xmlsecurity/biginteger.hxx>
48 : : #include <rtl/logfile.h>
49 : : #include <com/sun/star/task/XInteractionHandler.hpp>
50 : : #include <vector>
51 : : #include "boost/scoped_array.hpp"
52 : : #include <osl/thread.h>
53 : :
54 : : #include "secerror.hxx"
55 : :
56 : : // added for password exception
57 : : #include <com/sun/star/security/NoPasswordException.hpp>
58 : : namespace csss = ::com::sun::star::security;
59 : : using namespace xmlsecurity;
60 : : using namespace ::com::sun::star::security;
61 : : using namespace com::sun::star;
62 : : using namespace ::com::sun::star::uno ;
63 : : using namespace ::com::sun::star::lang ;
64 : : using ::com::sun::star::lang::XMultiServiceFactory ;
65 : : using ::com::sun::star::lang::XSingleServiceFactory ;
66 : : using ::rtl::OUString ;
67 : :
68 : : using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
69 : : using ::com::sun::star::security::XCertificate ;
70 : :
71 : : extern X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert ) ;
72 : : extern X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* ) ;
73 : :
74 : :
75 : : struct UsageDescription
76 : : {
77 : : SECCertificateUsage usage;
78 : : char const* description;
79 : :
80 : 0 : UsageDescription()
81 : : : usage( certificateUsageCheckAllUsages )
82 : 0 : , description( NULL )
83 : 0 : {}
84 : :
85 : 0 : UsageDescription( SECCertificateUsage i_usage, char const* i_description )
86 : : : usage( i_usage )
87 : 0 : , description( i_description )
88 : 0 : {}
89 : :
90 : : UsageDescription( const UsageDescription& aDescription )
91 : : : usage( aDescription.usage )
92 : : , description( aDescription.description )
93 : : {}
94 : :
95 : 0 : UsageDescription& operator =( const UsageDescription& aDescription )
96 : : {
97 : 0 : usage = aDescription.usage;
98 : 0 : description = aDescription.description;
99 : 0 : return *this;
100 : : }
101 : : };
102 : :
103 : :
104 : :
105 : 0 : char* GetPasswordFunction( PK11SlotInfo* pSlot, PRBool bRetry, void* /*arg*/ )
106 : : {
107 [ # # ]: 0 : uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
108 [ # # ]: 0 : if ( xMSF.is() )
109 : : {
110 : : uno::Reference < task::XInteractionHandler > xInteractionHandler(
111 [ # # ][ # # ]: 0 : xMSF->createInstance( rtl::OUString("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
[ # # ]
112 : :
113 [ # # ]: 0 : if ( xInteractionHandler.is() )
114 : : {
115 [ # # ]: 0 : task::PasswordRequestMode eMode = bRetry ? task::PasswordRequestMode_PASSWORD_REENTER : task::PasswordRequestMode_PASSWORD_ENTER;
116 : : ::comphelper::DocPasswordRequest* pPasswordRequest = new ::comphelper::DocPasswordRequest(
117 [ # # ][ # # ]: 0 : ::comphelper::DocPasswordRequestType_STANDARD, eMode, ::rtl::OUString::createFromAscii(PK11_GetTokenName(pSlot)) );
118 : :
119 [ # # ]: 0 : uno::Reference< task::XInteractionRequest > xRequest( pPasswordRequest );
120 [ # # ][ # # ]: 0 : xInteractionHandler->handle( xRequest );
121 : :
122 [ # # ][ # # ]: 0 : if ( pPasswordRequest->isPassword() )
123 : : {
124 : : rtl::OString aPassword(rtl::OUStringToOString(
125 : : pPasswordRequest->getPassword(),
126 [ # # ][ # # ]: 0 : osl_getThreadTextEncoding()));
[ # # ]
127 : 0 : sal_Int32 nLen = aPassword.getLength();
128 [ # # ]: 0 : char* pPassword = (char*) PORT_Alloc( nLen+1 ) ;
129 : 0 : pPassword[nLen] = 0;
130 : 0 : memcpy( pPassword, aPassword.getStr(), nLen );
131 : 0 : return pPassword;
132 [ # # ]: 0 : }
133 [ # # ]: 0 : }
134 : : }
135 : 0 : return NULL;
136 : : }
137 : :
138 : 0 : SecurityEnvironment_NssImpl :: SecurityEnvironment_NssImpl( const Reference< XMultiServiceFactory >& ) :
139 [ # # ][ # # ]: 0 : m_pHandler( NULL ) , m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList() {
[ # # ][ # # ]
[ # # ]
140 : :
141 [ # # ]: 0 : PK11_SetPasswordFunc( GetPasswordFunction ) ;
142 : 0 : }
143 : :
144 [ # # ]: 0 : SecurityEnvironment_NssImpl :: ~SecurityEnvironment_NssImpl() {
145 : :
146 [ # # ]: 0 : PK11_SetPasswordFunc( NULL ) ;
147 : :
148 [ # # ]: 0 : for (CIT_SLOTS i = m_Slots.begin(); i != m_Slots.end(); i++)
149 : : {
150 [ # # ]: 0 : PK11_FreeSlot(*i);
151 : : }
152 : :
153 [ # # ]: 0 : if( !m_tSymKeyList.empty() ) {
154 : 0 : std::list< PK11SymKey* >::iterator symKeyIt ;
155 : :
156 [ # # ]: 0 : for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; ++symKeyIt )
157 [ # # ]: 0 : PK11_FreeSymKey( *symKeyIt ) ;
158 : : }
159 : :
160 [ # # ]: 0 : if( !m_tPubKeyList.empty() ) {
161 : 0 : std::list< SECKEYPublicKey* >::iterator pubKeyIt ;
162 : :
163 [ # # ]: 0 : for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; ++pubKeyIt )
164 [ # # ]: 0 : SECKEY_DestroyPublicKey( *pubKeyIt ) ;
165 : : }
166 : :
167 [ # # ]: 0 : if( !m_tPriKeyList.empty() ) {
168 : 0 : std::list< SECKEYPrivateKey* >::iterator priKeyIt ;
169 : :
170 [ # # ]: 0 : for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; ++priKeyIt )
171 [ # # ]: 0 : SECKEY_DestroyPrivateKey( *priKeyIt ) ;
172 : : }
173 [ # # ]: 0 : }
174 : :
175 : : /* XInitialization */
176 : 0 : void SAL_CALL SecurityEnvironment_NssImpl :: initialize( const Sequence< Any >& ) throw( Exception, RuntimeException ) {
177 : : // TBD
178 : 0 : } ;
179 : :
180 : : /* XServiceInfo */
181 : 0 : OUString SAL_CALL SecurityEnvironment_NssImpl :: getImplementationName() throw( RuntimeException ) {
182 : 0 : return impl_getImplementationName() ;
183 : : }
184 : :
185 : : /* XServiceInfo */
186 : 0 : sal_Bool SAL_CALL SecurityEnvironment_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
187 [ # # ]: 0 : Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
188 : 0 : const OUString* pArray = seqServiceNames.getConstArray() ;
189 [ # # ]: 0 : for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
190 [ # # ]: 0 : if( *( pArray + i ) == serviceName )
191 : 0 : return sal_True ;
192 : : }
193 [ # # ]: 0 : return sal_False ;
194 : : }
195 : :
196 : : /* XServiceInfo */
197 : 0 : Sequence< OUString > SAL_CALL SecurityEnvironment_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
198 : 0 : return impl_getSupportedServiceNames() ;
199 : : }
200 : :
201 : : //Helper for XServiceInfo
202 : 0 : Sequence< OUString > SecurityEnvironment_NssImpl :: impl_getSupportedServiceNames() {
203 [ # # ][ # # ]: 0 : ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
204 [ # # ]: 0 : Sequence< OUString > seqServiceNames( 1 ) ;
205 [ # # ]: 0 : seqServiceNames.getArray()[0] = OUString("com.sun.star.xml.crypto.SecurityEnvironment") ;
206 [ # # ]: 0 : return seqServiceNames ;
207 : : }
208 : :
209 : 0 : OUString SecurityEnvironment_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
210 : 0 : return OUString("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl") ;
211 : : }
212 : :
213 : : //Helper for registry
214 : 0 : Reference< XInterface > SAL_CALL SecurityEnvironment_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
215 [ # # ]: 0 : return Reference< XInterface >( *new SecurityEnvironment_NssImpl( aServiceManager ) ) ;
216 : : }
217 : :
218 : 0 : Reference< XSingleServiceFactory > SecurityEnvironment_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
219 [ # # ][ # # ]: 0 : return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
220 : : }
221 : :
222 : : /* XUnoTunnel */
223 : 0 : sal_Int64 SAL_CALL SecurityEnvironment_NssImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
224 : : throw( RuntimeException )
225 : : {
226 [ # # ][ # # ]: 0 : if( aIdentifier.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
[ # # ]
227 : 0 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
228 : : }
229 : 0 : return 0 ;
230 : : }
231 : :
232 : : /* XUnoTunnel extension */
233 : :
234 : : namespace
235 : : {
236 : : class theSecurityEnvironment_NssImplUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSecurityEnvironment_NssImplUnoTunnelId > {};
237 : : }
238 : :
239 : 0 : const Sequence< sal_Int8>& SecurityEnvironment_NssImpl :: getUnoTunnelId() {
240 : 0 : return theSecurityEnvironment_NssImplUnoTunnelId::get().getSeq();
241 : : }
242 : :
243 : 0 : ::rtl::OUString SecurityEnvironment_NssImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
244 : : {
245 : 0 : rtl::OUString result;
246 : 0 : ::rtl::OUStringBuffer buff;
247 [ # # ]: 0 : for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
248 : : {
249 [ # # ][ # # ]: 0 : buff.append(rtl::OUString::createFromAscii(PK11_GetTokenName(*is)));
250 [ # # ]: 0 : buff.appendAscii("\n");
251 : : }
252 [ # # ]: 0 : return buff.makeStringAndClear();
253 : : }
254 : :
255 : 0 : void SecurityEnvironment_NssImpl::addCryptoSlot( PK11SlotInfo* aSlot) throw( Exception , RuntimeException )
256 : : {
257 : 0 : PK11_ReferenceSlot(aSlot);
258 : 0 : m_Slots.push_back(aSlot);
259 : 0 : }
260 : :
261 : 0 : CERTCertDBHandle* SecurityEnvironment_NssImpl :: getCertDb() throw( Exception , RuntimeException ) {
262 : 0 : return m_pHandler ;
263 : : }
264 : :
265 : : //Could we have multiple cert dbs?
266 : 0 : void SecurityEnvironment_NssImpl :: setCertDb( CERTCertDBHandle* aCertDb ) throw( Exception , RuntimeException ) {
267 : 0 : m_pHandler = aCertDb ;
268 : 0 : }
269 : :
270 : 0 : void SecurityEnvironment_NssImpl :: adoptSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) {
271 : : PK11SymKey* symkey ;
272 : 0 : std::list< PK11SymKey* >::iterator keyIt ;
273 : :
274 [ # # ]: 0 : if( aSymKey != NULL ) {
275 : : //First try to find the key in the list
276 [ # # ]: 0 : for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) {
277 [ # # ]: 0 : if( *keyIt == aSymKey )
278 : 0 : return ;
279 : : }
280 : :
281 : : //If we do not find the key in the list, add a new node
282 [ # # ]: 0 : symkey = PK11_ReferenceSymKey( aSymKey ) ;
283 [ # # ]: 0 : if( symkey == NULL )
284 [ # # ]: 0 : throw RuntimeException() ;
285 : :
286 : : try {
287 [ # # ]: 0 : m_tSymKeyList.push_back( symkey ) ;
288 [ # # # # ]: 0 : } catch ( Exception& ) {
289 [ # # ]: 0 : PK11_FreeSymKey( symkey ) ;
290 : : }
291 : : }
292 : : }
293 : :
294 : 0 : void SecurityEnvironment_NssImpl :: rejectSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) {
295 : : PK11SymKey* symkey ;
296 : 0 : std::list< PK11SymKey* >::iterator keyIt ;
297 : :
298 [ # # ]: 0 : if( aSymKey != NULL ) {
299 [ # # ]: 0 : for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) {
300 [ # # ]: 0 : if( *keyIt == aSymKey ) {
301 : 0 : symkey = *keyIt ;
302 [ # # ]: 0 : PK11_FreeSymKey( symkey ) ;
303 [ # # ]: 0 : m_tSymKeyList.erase( keyIt ) ;
304 : 0 : break ;
305 : : }
306 : : }
307 : : }
308 : 0 : }
309 : :
310 : 0 : PK11SymKey* SecurityEnvironment_NssImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
311 : : PK11SymKey* symkey ;
312 : 0 : std::list< PK11SymKey* >::iterator keyIt ;
313 : : unsigned int pos ;
314 : :
315 : 0 : symkey = NULL ;
316 [ # # ][ # # ]: 0 : for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
[ # # ][ # # ]
317 : :
318 [ # # ][ # # ]: 0 : if( pos == position && keyIt != m_tSymKeyList.end() )
[ # # ][ # # ]
319 : 0 : symkey = *keyIt ;
320 : :
321 : 0 : return symkey ;
322 : : }
323 : :
324 : 0 : void SecurityEnvironment_NssImpl :: adoptPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) {
325 : : SECKEYPublicKey* pubkey ;
326 : 0 : std::list< SECKEYPublicKey* >::iterator keyIt ;
327 : :
328 [ # # ]: 0 : if( aPubKey != NULL ) {
329 : : //First try to find the key in the list
330 [ # # ]: 0 : for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) {
331 [ # # ]: 0 : if( *keyIt == aPubKey )
332 : 0 : return ;
333 : : }
334 : :
335 : : //If we do not find the key in the list, add a new node
336 [ # # ]: 0 : pubkey = SECKEY_CopyPublicKey( aPubKey ) ;
337 [ # # ]: 0 : if( pubkey == NULL )
338 [ # # ]: 0 : throw RuntimeException() ;
339 : :
340 : : try {
341 [ # # ]: 0 : m_tPubKeyList.push_back( pubkey ) ;
342 [ # # # # ]: 0 : } catch ( Exception& ) {
343 [ # # ]: 0 : SECKEY_DestroyPublicKey( pubkey ) ;
344 : : }
345 : : }
346 : : }
347 : :
348 : 0 : void SecurityEnvironment_NssImpl :: rejectPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) {
349 : : SECKEYPublicKey* pubkey ;
350 : 0 : std::list< SECKEYPublicKey* >::iterator keyIt ;
351 : :
352 [ # # ]: 0 : if( aPubKey != NULL ) {
353 [ # # ]: 0 : for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) {
354 [ # # ]: 0 : if( *keyIt == aPubKey ) {
355 : 0 : pubkey = *keyIt ;
356 [ # # ]: 0 : SECKEY_DestroyPublicKey( pubkey ) ;
357 [ # # ]: 0 : m_tPubKeyList.erase( keyIt ) ;
358 : 0 : break ;
359 : : }
360 : : }
361 : : }
362 : 0 : }
363 : :
364 : 0 : SECKEYPublicKey* SecurityEnvironment_NssImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
365 : : SECKEYPublicKey* pubkey ;
366 : 0 : std::list< SECKEYPublicKey* >::iterator keyIt ;
367 : : unsigned int pos ;
368 : :
369 : 0 : pubkey = NULL ;
370 [ # # ][ # # ]: 0 : for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
[ # # ][ # # ]
371 : :
372 [ # # ][ # # ]: 0 : if( pos == position && keyIt != m_tPubKeyList.end() )
[ # # ][ # # ]
373 : 0 : pubkey = *keyIt ;
374 : :
375 : 0 : return pubkey ;
376 : : }
377 : :
378 : 0 : void SecurityEnvironment_NssImpl :: adoptPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) {
379 : : SECKEYPrivateKey* prikey ;
380 : 0 : std::list< SECKEYPrivateKey* >::iterator keyIt ;
381 : :
382 [ # # ]: 0 : if( aPriKey != NULL ) {
383 : : //First try to find the key in the list
384 [ # # ]: 0 : for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) {
385 [ # # ]: 0 : if( *keyIt == aPriKey )
386 : 0 : return ;
387 : : }
388 : :
389 : : //If we do not find the key in the list, add a new node
390 [ # # ]: 0 : prikey = SECKEY_CopyPrivateKey( aPriKey ) ;
391 [ # # ]: 0 : if( prikey == NULL )
392 [ # # ]: 0 : throw RuntimeException() ;
393 : :
394 : : try {
395 [ # # ]: 0 : m_tPriKeyList.push_back( prikey ) ;
396 [ # # # # ]: 0 : } catch ( Exception& ) {
397 [ # # ]: 0 : SECKEY_DestroyPrivateKey( prikey ) ;
398 : : }
399 : : }
400 : : }
401 : :
402 : 0 : void SecurityEnvironment_NssImpl :: rejectPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) {
403 : : SECKEYPrivateKey* prikey ;
404 : 0 : std::list< SECKEYPrivateKey* >::iterator keyIt ;
405 : :
406 [ # # ]: 0 : if( aPriKey != NULL ) {
407 [ # # ]: 0 : for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) {
408 [ # # ]: 0 : if( *keyIt == aPriKey ) {
409 : 0 : prikey = *keyIt ;
410 [ # # ]: 0 : SECKEY_DestroyPrivateKey( prikey ) ;
411 [ # # ]: 0 : m_tPriKeyList.erase( keyIt ) ;
412 : 0 : break ;
413 : : }
414 : : }
415 : : }
416 : 0 : }
417 : :
418 : 0 : SECKEYPrivateKey* SecurityEnvironment_NssImpl :: getPriKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
419 : : SECKEYPrivateKey* prikey ;
420 : 0 : std::list< SECKEYPrivateKey* >::iterator keyIt ;
421 : : unsigned int pos ;
422 : :
423 : 0 : prikey = NULL ;
424 [ # # ][ # # ]: 0 : for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
[ # # ][ # # ]
425 : :
426 [ # # ][ # # ]: 0 : if( pos == position && keyIt != m_tPriKeyList.end() )
[ # # ][ # # ]
427 : 0 : prikey = *keyIt ;
428 : :
429 : 0 : return prikey ;
430 : : }
431 : :
432 : 0 : void SecurityEnvironment_NssImpl::updateSlots()
433 : : {
434 : : //In case new tokens are present then we can obtain the corresponding slot
435 : 0 : PK11SlotList * soltList = NULL;
436 : 0 : PK11SlotListElement * soltEle = NULL;
437 : 0 : PK11SlotInfo * pSlot = NULL;
438 : 0 : PK11SymKey * pSymKey = NULL;
439 : :
440 [ # # ]: 0 : osl::MutexGuard guard(m_mutex);
441 : :
442 : 0 : m_Slots.clear();
443 : 0 : m_tSymKeyList.clear();
444 : :
445 [ # # ]: 0 : soltList = PK11_GetAllTokens( CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL ) ;
446 [ # # ]: 0 : if( soltList != NULL )
447 : : {
448 [ # # ]: 0 : for( soltEle = soltList->head ; soltEle != NULL; soltEle = soltEle->next )
449 : : {
450 : 0 : pSlot = soltEle->slot ;
451 : :
452 [ # # ]: 0 : if(pSlot != NULL)
453 : : {
454 : : RTL_LOGFILE_TRACE2( "XMLSEC: Found a slot: SlotName=%s, TokenName=%s", PK11_GetSlotName(pSlot), PK11_GetTokenName(pSlot) );
455 : :
456 : : //The following code which is commented out checks if a slot, that is a smart card for example, is
457 : : // able to generate a symmetric key of type CKM_DES3_CBC. If this fails then this token
458 : : // will not be used. This key is possibly used for the encryption service. However, all
459 : : // interfaces and services used for public key signature and encryption are not published
460 : : // and the encryption is not used in OOo. Therefore it does not do any harm to remove
461 : : // this code, hence allowing smart cards which cannot generate this type of key.
462 : : //
463 : : // By doing this, the encryption may fail if a smart card is being used which does not
464 : : // support this key generation.
465 : : //
466 [ # # ]: 0 : pSymKey = PK11_KeyGen( pSlot , CKM_DES3_CBC, NULL, 128, NULL ) ;
467 : : // if( pSymKey == NULL )
468 : : // {
469 : : // PK11_FreeSlot( pSlot ) ;
470 : : // RTL_LOGFILE_TRACE( "XMLSEC: Error - pSymKey is NULL" );
471 : : // continue;
472 : : // }
473 [ # # ]: 0 : addCryptoSlot(pSlot);
474 [ # # ]: 0 : PK11_FreeSlot( pSlot ) ;
475 : 0 : pSlot = NULL;
476 : :
477 [ # # ]: 0 : if (pSymKey != NULL)
478 : : {
479 [ # # ]: 0 : adoptSymKey( pSymKey ) ;
480 [ # # ]: 0 : PK11_FreeSymKey( pSymKey ) ;
481 : 0 : pSymKey = NULL;
482 : : }
483 : :
484 : : }// end of if(pSlot != NULL)
485 : : }// end of for
486 [ # # ]: 0 : }// end of if( soltList != NULL )
487 : :
488 : 0 : }
489 : :
490 : :
491 : : Sequence< Reference < XCertificate > >
492 : 0 : SecurityEnvironment_NssImpl::getPersonalCertificates() throw( SecurityException , RuntimeException )
493 : : {
494 : : sal_Int32 length ;
495 : : X509Certificate_NssImpl* xcert ;
496 [ # # ]: 0 : std::list< X509Certificate_NssImpl* > certsList ;
497 : :
498 [ # # ]: 0 : updateSlots();
499 : : //firstly, we try to find private keys in slot
500 [ # # ]: 0 : for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
501 : : {
502 : 0 : PK11SlotInfo *slot = *is;
503 : : SECKEYPrivateKeyList* priKeyList ;
504 : : SECKEYPrivateKeyListNode* curPri ;
505 : :
506 [ # # ][ # # ]: 0 : if( PK11_NeedLogin(slot ) ) {
507 [ # # ]: 0 : SECStatus nRet = PK11_Authenticate(slot, PR_TRUE, NULL);
508 : : //PK11_Authenticate may fail in case the a slot has not been initialized.
509 : : //this is the case if the user has a new profile, so that they have never
510 : : //added a personal certificate.
511 [ # # ][ # # ]: 0 : if( nRet != SECSuccess && PORT_GetError() != SEC_ERROR_IO) {
[ # # ][ # # ]
512 [ # # ]: 0 : throw NoPasswordException();
513 : : }
514 : : }
515 : :
516 [ # # ]: 0 : priKeyList = PK11_ListPrivateKeysInSlot(slot) ;
517 [ # # ]: 0 : if( priKeyList != NULL ) {
518 [ # # ][ # # ]: 0 : for( curPri = PRIVKEY_LIST_HEAD( priKeyList );
[ # # ]
519 : 0 : !PRIVKEY_LIST_END( curPri, priKeyList ) && curPri != NULL ;
520 : : curPri = PRIVKEY_LIST_NEXT( curPri ) ) {
521 [ # # ]: 0 : xcert = NssPrivKeyToXCert( curPri->key ) ;
522 [ # # ]: 0 : if( xcert != NULL )
523 [ # # ]: 0 : certsList.push_back( xcert ) ;
524 : : }
525 : : }
526 : :
527 [ # # ]: 0 : SECKEY_DestroyPrivateKeyList( priKeyList ) ;
528 : : }
529 : :
530 : : //secondly, we try to find certificate from registered private keys.
531 [ # # ]: 0 : if( !m_tPriKeyList.empty() ) {
532 : 0 : std::list< SECKEYPrivateKey* >::iterator priKeyIt ;
533 : :
534 [ # # ]: 0 : for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; ++priKeyIt ) {
535 [ # # ]: 0 : xcert = NssPrivKeyToXCert( *priKeyIt ) ;
536 [ # # ]: 0 : if( xcert != NULL )
537 [ # # ]: 0 : certsList.push_back( xcert ) ;
538 : : }
539 : : }
540 : :
541 : 0 : length = certsList.size() ;
542 [ # # ]: 0 : if( length != 0 ) {
543 : : int i ;
544 : 0 : std::list< X509Certificate_NssImpl* >::iterator xcertIt ;
545 [ # # ]: 0 : Sequence< Reference< XCertificate > > certSeq( length ) ;
546 : :
547 [ # # ]: 0 : for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); ++xcertIt, ++i ) {
548 [ # # ][ # # ]: 0 : certSeq[i] = *xcertIt ;
[ # # ]
549 : : }
550 : :
551 [ # # ][ # # ]: 0 : return certSeq ;
552 : : }
553 : :
554 [ # # ]: 0 : return Sequence< Reference < XCertificate > > ();
555 : : }
556 : :
557 : 0 : Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException )
558 : : {
559 : 0 : X509Certificate_NssImpl* xcert = NULL;
560 : :
561 [ # # ]: 0 : if( m_pHandler != NULL ) {
562 : : CERTIssuerAndSN issuerAndSN ;
563 : : CERTCertificate* cert ;
564 : : CERTName* nmIssuer ;
565 : : char* chIssuer ;
566 : : SECItem* derIssuer ;
567 : : PRArenaPool* arena ;
568 : :
569 [ # # ]: 0 : arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ) ;
570 [ # # ]: 0 : if( arena == NULL )
571 [ # # ]: 0 : throw RuntimeException() ;
572 : :
573 : : // Create cert info from issue and serial
574 [ # # ]: 0 : rtl::OString ostr = rtl::OUStringToOString( issuerName , RTL_TEXTENCODING_UTF8 ) ;
575 [ # # ]: 0 : chIssuer = PL_strndup( ( char* )ostr.getStr(), ( int )ostr.getLength() ) ;
576 [ # # ]: 0 : nmIssuer = CERT_AsciiToName( chIssuer ) ;
577 [ # # ]: 0 : if( nmIssuer == NULL ) {
578 [ # # ]: 0 : PL_strfree( chIssuer ) ;
579 [ # # ]: 0 : PORT_FreeArena( arena, PR_FALSE ) ;
580 [ # # ]: 0 : return NULL; // no need for exception cf. i40394
581 : : }
582 : :
583 [ # # ]: 0 : derIssuer = SEC_ASN1EncodeItem( arena, NULL, ( void* )nmIssuer, SEC_ASN1_GET( CERT_NameTemplate ) ) ;
584 [ # # ]: 0 : if( derIssuer == NULL ) {
585 [ # # ]: 0 : PL_strfree( chIssuer ) ;
586 [ # # ]: 0 : CERT_DestroyName( nmIssuer ) ;
587 [ # # ]: 0 : PORT_FreeArena( arena, PR_FALSE ) ;
588 [ # # ]: 0 : throw RuntimeException() ;
589 : : }
590 : :
591 : 0 : memset( &issuerAndSN, 0, sizeof( issuerAndSN ) ) ;
592 : :
593 : 0 : issuerAndSN.derIssuer.data = derIssuer->data ;
594 : 0 : issuerAndSN.derIssuer.len = derIssuer->len ;
595 : :
596 : 0 : issuerAndSN.serialNumber.data = ( unsigned char* )&serialNumber[0] ;
597 : 0 : issuerAndSN.serialNumber.len = serialNumber.getLength() ;
598 : :
599 [ # # ]: 0 : cert = CERT_FindCertByIssuerAndSN( m_pHandler, &issuerAndSN ) ;
600 [ # # ]: 0 : if( cert != NULL ) {
601 [ # # ]: 0 : xcert = NssCertToXCert( cert ) ;
602 : : } else {
603 : 0 : xcert = NULL ;
604 : : }
605 : :
606 [ # # ]: 0 : PL_strfree( chIssuer ) ;
607 [ # # ]: 0 : CERT_DestroyName( nmIssuer ) ;
608 : : //SECITEM_FreeItem( derIssuer, PR_FALSE ) ;
609 [ # # ]: 0 : CERT_DestroyCertificate( cert ) ;
610 [ # # ][ # # ]: 0 : PORT_FreeArena( arena, PR_FALSE ) ;
611 : : } else {
612 : 0 : xcert = NULL ;
613 : : }
614 : :
615 [ # # ]: 0 : return xcert ;
616 : : }
617 : :
618 : 0 : Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
619 [ # # ]: 0 : Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
620 [ # # ][ # # ]: 0 : return getCertificate( issuerName, serial ) ;
621 : : }
622 : :
623 : 0 : Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
624 : : const X509Certificate_NssImpl* xcert ;
625 : : const CERTCertificate* cert ;
626 : : CERTCertList* certChain ;
627 : :
628 [ # # ]: 0 : Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
629 [ # # ]: 0 : if( !xCertTunnel.is() ) {
630 [ # # ]: 0 : throw RuntimeException() ;
631 : : }
632 : :
633 : : xcert = reinterpret_cast<X509Certificate_NssImpl*>(
634 [ # # ][ # # ]: 0 : sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
[ # # ]
635 [ # # ]: 0 : if( xcert == NULL ) {
636 [ # # ]: 0 : throw RuntimeException() ;
637 : : }
638 : :
639 [ # # ]: 0 : cert = xcert->getNssCert() ;
640 [ # # ]: 0 : if( cert != NULL ) {
641 : : int64 timeboundary ;
642 : :
643 : : //Get the system clock time
644 [ # # ]: 0 : timeboundary = PR_Now() ;
645 : :
646 [ # # ]: 0 : certChain = CERT_GetCertChainFromCert( ( CERTCertificate* )cert, timeboundary, certUsageAnyCA ) ;
647 : : } else {
648 : 0 : certChain = NULL ;
649 : : }
650 : :
651 [ # # ]: 0 : if( certChain != NULL ) {
652 : : X509Certificate_NssImpl* pCert ;
653 : : CERTCertListNode* node ;
654 : : int len ;
655 : :
656 [ # # ]: 0 : for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) ;
657 [ # # ]: 0 : Sequence< Reference< XCertificate > > xCertChain( len ) ;
658 : :
659 [ # # ]: 0 : for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) {
660 [ # # ]: 0 : pCert = new X509Certificate_NssImpl() ;
661 [ # # ]: 0 : if( pCert == NULL ) {
662 [ # # ]: 0 : CERT_DestroyCertList( certChain ) ;
663 [ # # ]: 0 : throw RuntimeException() ;
664 : : }
665 : :
666 [ # # ]: 0 : pCert->setCert( node->cert ) ;
667 : :
668 [ # # ][ # # ]: 0 : xCertChain[len] = pCert ;
[ # # ]
669 : : }
670 : :
671 [ # # ]: 0 : CERT_DestroyCertList( certChain ) ;
672 : :
673 [ # # ][ # # ]: 0 : return xCertChain ;
674 : : }
675 : :
676 [ # # ]: 0 : return Sequence< Reference < XCertificate > >();
677 : : }
678 : :
679 : 0 : Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
680 : : X509Certificate_NssImpl* xcert ;
681 : :
682 [ # # ]: 0 : if( rawCertificate.getLength() > 0 ) {
683 [ # # ]: 0 : xcert = new X509Certificate_NssImpl() ;
684 [ # # ]: 0 : if( xcert == NULL )
685 [ # # ]: 0 : throw RuntimeException() ;
686 : :
687 [ # # ]: 0 : xcert->setRawCert( rawCertificate ) ;
688 : : } else {
689 : 0 : xcert = NULL ;
690 : : }
691 : :
692 [ # # ]: 0 : return xcert ;
693 : : }
694 : :
695 : 0 : Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
696 : : xmlChar* chCert ;
697 : : xmlSecSize certSize ;
698 : :
699 [ # # ]: 0 : rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
700 : :
701 [ # # ]: 0 : chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
702 : :
703 [ # # ][ # # ]: 0 : certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
704 : :
705 [ # # ]: 0 : Sequence< sal_Int8 > rawCert( certSize ) ;
706 [ # # ]: 0 : for( unsigned int i = 0 ; i < certSize ; i ++ )
707 [ # # ]: 0 : rawCert[i] = *( chCert + i ) ;
708 : :
709 [ # # ]: 0 : xmlFree( chCert ) ;
710 : :
711 [ # # ][ # # ]: 0 : return createCertificateFromRaw( rawCert ) ;
712 : : }
713 : :
714 : 0 : sal_Int32 SecurityEnvironment_NssImpl ::
715 : : verifyCertificate( const Reference< csss::XCertificate >& aCert,
716 : : const Sequence< Reference< csss::XCertificate > >& intermediateCerts )
717 : : throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException )
718 : : {
719 : 0 : sal_Int32 validity = csss::CertificateValidity::INVALID;
720 : : const X509Certificate_NssImpl* xcert ;
721 : : const CERTCertificate* cert ;
722 [ # # ]: 0 : ::std::vector<CERTCertificate*> vecTmpNSSCertificates;
723 [ # # ]: 0 : Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
724 [ # # ]: 0 : if( !xCertTunnel.is() ) {
725 [ # # ]: 0 : throw RuntimeException() ;
726 : : }
727 : :
728 : : xmlsec_trace("Start verification of certificate: \n %s \n",
729 : : OUStringToOString(
730 [ # # ][ # # ]: 0 : aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr());
[ # # ][ # # ]
[ # # ]
731 : :
732 : : xcert = reinterpret_cast<X509Certificate_NssImpl*>(
733 [ # # ][ # # ]: 0 : sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
[ # # ]
734 [ # # ]: 0 : if( xcert == NULL ) {
735 [ # # ]: 0 : throw RuntimeException() ;
736 : : }
737 : :
738 : : //CERT_PKIXVerifyCert does not take a db as argument. It will therefore
739 : : //internally use CERT_GetDefaultCertDB
740 : : //Make sure m_pHandler is the default DB
741 : : OSL_ASSERT(m_pHandler == CERT_GetDefaultCertDB());
742 [ # # ][ # # ]: 0 : CERTCertDBHandle * certDb = m_pHandler != NULL ? m_pHandler : CERT_GetDefaultCertDB();
743 [ # # ]: 0 : cert = xcert->getNssCert() ;
744 [ # # ]: 0 : if( cert != NULL )
745 : : {
746 : :
747 : : //prepare the intermediate certificates
748 [ # # ]: 0 : for (sal_Int32 i = 0; i < intermediateCerts.getLength(); i++)
749 : : {
750 [ # # ][ # # ]: 0 : Sequence<sal_Int8> der = intermediateCerts[i]->getEncoded();
751 : : SECItem item;
752 : 0 : item.type = siBuffer;
753 [ # # ]: 0 : item.data = (unsigned char*)der.getArray();
754 : 0 : item.len = der.getLength();
755 : :
756 : : CERTCertificate* certTmp = CERT_NewTempCertificate(certDb, &item,
757 : : NULL /* nickname */,
758 : : PR_FALSE /* isPerm */,
759 [ # # ]: 0 : PR_TRUE /* copyDER */);
760 [ # # ]: 0 : if (!certTmp)
761 : : {
762 : : xmlsec_trace("Failed to add a temporary certificate: %s",
763 [ # # ]: 0 : OUStringToOString(intermediateCerts[i]->getIssuerName(),
764 [ # # ][ # # ]: 0 : osl_getThreadTextEncoding()).getStr());
[ # # ][ # # ]
765 : :
766 : : }
767 : : else
768 : : {
769 : : xmlsec_trace("Added temporary certificate: %s",
770 [ # # ][ # # ]: 0 : certTmp->subjectName ? certTmp->subjectName : "");
771 [ # # ]: 0 : vecTmpNSSCertificates.push_back(certTmp);
772 : : }
773 [ # # ]: 0 : }
774 : :
775 : :
776 : : SECStatus status ;
777 : :
778 : : CERTVerifyLog log;
779 [ # # ]: 0 : log.arena = PORT_NewArena(512);
780 : 0 : log.head = log.tail = NULL;
781 : 0 : log.count = 0;
782 : :
783 [ # # ]: 0 : CERT_EnableOCSPChecking(certDb);
784 [ # # ]: 0 : CERT_DisableOCSPDefaultResponder(certDb);
785 : : CERTValOutParam cvout[5];
786 : : CERTValInParam cvin[3];
787 : 0 : int ncvinCount=0;
788 : :
789 : : #if ( NSS_VMAJOR > 3 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR > 12 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH > 0 )
790 : 0 : cvin[ncvinCount].type = cert_pi_useAIACertFetch;
791 : 0 : cvin[ncvinCount].value.scalar.b = PR_TRUE;
792 : 0 : ncvinCount++;
793 : : #endif
794 : :
795 : : PRUint64 revFlagsLeaf[2];
796 : : PRUint64 revFlagsChain[2];
797 : : CERTRevocationFlags rev;
798 : 0 : rev.leafTests.number_of_defined_methods = 2;
799 : 0 : rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
800 : : //the flags are defined in cert.h
801 : : //We check both leaf and chain.
802 : : //It is enough if one revocation method has fresh info,
803 : : //but at least one must have some. Otherwise validation fails.
804 : : //!!! using leaf test and CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE
805 : : // when validating a root certificate will result in "revoked". Usually
806 : : //there is no revocation information available for the root cert because
807 : : //it must be trusted anyway and it does itself issue revocation information.
808 : : //When we use the flag here and OOo shows the certification path then the root
809 : : //cert is invalid while all other can be valid. It would probably best if
810 : : //this interface method returned the whole chain.
811 : : //Otherwise we need to check if the certificate is self-signed and if it is
812 : : //then not use the flag when doing the leaf-test.
813 : 0 : rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
814 : : CERT_REV_M_TEST_USING_THIS_METHOD
815 : 0 : | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
816 : 0 : rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] =
817 : : CERT_REV_M_TEST_USING_THIS_METHOD
818 : 0 : | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
819 : 0 : rev.leafTests.number_of_preferred_methods = 0;
820 : 0 : rev.leafTests.preferred_methods = NULL;
821 : : rev.leafTests.cert_rev_method_independent_flags =
822 : 0 : CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST;
823 : :
824 : 0 : rev.chainTests.number_of_defined_methods = 2;
825 : 0 : rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
826 : 0 : rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
827 : : CERT_REV_M_TEST_USING_THIS_METHOD
828 : 0 : | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
829 : 0 : rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] =
830 : : CERT_REV_M_TEST_USING_THIS_METHOD
831 : 0 : | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
832 : 0 : rev.chainTests.number_of_preferred_methods = 0;
833 : 0 : rev.chainTests.preferred_methods = NULL;
834 : : rev.chainTests.cert_rev_method_independent_flags =
835 : 0 : CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST;
836 : :
837 : :
838 : 0 : cvin[ncvinCount].type = cert_pi_revocationFlags;
839 : 0 : cvin[ncvinCount].value.pointer.revocation = &rev;
840 : 0 : ncvinCount++;
841 : : // does not work, not implemented yet in 3.12.4
842 : : // cvin[ncvinCount].type = cert_pi_keyusage;
843 : : // cvin[ncvinCount].value.scalar.ui = KU_DIGITAL_SIGNATURE;
844 : : // ncvinCount++;
845 : 0 : cvin[ncvinCount].type = cert_pi_end;
846 : :
847 : 0 : cvout[0].type = cert_po_trustAnchor;
848 : 0 : cvout[0].value.pointer.cert = NULL;
849 : 0 : cvout[1].type = cert_po_errorLog;
850 : 0 : cvout[1].value.pointer.log = &log;
851 : 0 : cvout[2].type = cert_po_end;
852 : :
853 : : // We check SSL server certificates, CA certificates and signing sertificates.
854 : : //
855 : : // ToDo check keyusage, looking at CERT_KeyUsageAndTypeForCertUsage (
856 : : // mozilla/security/nss/lib/certdb/certdb.c indicates that
857 : : // certificateUsageSSLClient, certificateUsageSSLServer and certificateUsageSSLCA
858 : : // are sufficient. They cover the key usages for digital signature, key agreement
859 : : // and encipherment and certificate signature
860 : :
861 : : //never use the following usages because they are not checked properly
862 : : // certificateUsageUserCertImport
863 : : // certificateUsageVerifyCA
864 : : // certificateUsageAnyCA
865 : : // certificateUsageProtectedObjectSigner
866 : :
867 [ # # ]: 0 : UsageDescription arUsages[5];
868 : 0 : arUsages[0] = UsageDescription( certificateUsageSSLClient, "certificateUsageSSLClient" );
869 : 0 : arUsages[1] = UsageDescription( certificateUsageSSLServer, "certificateUsageSSLServer" );
870 : 0 : arUsages[2] = UsageDescription( certificateUsageSSLCA, "certificateUsageSSLCA" );
871 : 0 : arUsages[3] = UsageDescription( certificateUsageEmailSigner, "certificateUsageEmailSigner" );
872 : 0 : arUsages[4] = UsageDescription( certificateUsageEmailRecipient, "certificateUsageEmailRecipient" );
873 : :
874 : 0 : int numUsages = SAL_N_ELEMENTS(arUsages);
875 [ # # ]: 0 : for (int i = 0; i < numUsages; i++)
876 : : {
877 : : xmlsec_trace("Testing usage %d of %d: %s (0x%x)", i + 1,
878 [ # # ]: 0 : numUsages, arUsages[i].description, (int) arUsages[i].usage);
879 : :
880 : : status = CERT_PKIXVerifyCert(const_cast<CERTCertificate *>(cert), arUsages[i].usage,
881 [ # # ]: 0 : cvin, cvout, NULL);
882 [ # # ]: 0 : if( status == SECSuccess )
883 : : {
884 [ # # ]: 0 : xmlsec_trace("CERT_PKIXVerifyCert returned SECSuccess.");
885 : : //When an intermediate or root certificate is checked then we expect the usage
886 : : //certificateUsageSSLCA. This, however, will be only set when in the trust settings dialog
887 : : //the button "This certificate can identify websites" is checked. If for example only
888 : : //"This certificate can identify mail users" is set then the end certificate can
889 : : //be validated and the returned usage will conain certificateUsageEmailRecipient.
890 : : //But checking directly the root or intermediate certificate will fail. In the
891 : : //certificate path view the end certificate will be shown as valid but the others
892 : : //will be displayed as invalid.
893 : :
894 : 0 : validity = csss::CertificateValidity::VALID;
895 [ # # ]: 0 : xmlsec_trace("Certificate is valid.\n");
896 : 0 : CERTCertificate * issuerCert = cvout[0].value.pointer.cert;
897 [ # # ]: 0 : if (issuerCert)
898 : : {
899 [ # # ]: 0 : xmlsec_trace("Root certificate: %s", issuerCert->subjectName);
900 [ # # ]: 0 : CERT_DestroyCertificate(issuerCert);
901 : : };
902 : :
903 : 0 : break;
904 : : }
905 : : else
906 : : {
907 [ # # ]: 0 : PRIntn err = PR_GetError();
908 [ # # ][ # # ]: 0 : xmlsec_trace("Error: , %d = %s", err, getCertError(err));
909 : :
910 : : /* Display validation results */
911 [ # # ]: 0 : if ( log.count > 0)
912 : : {
913 : 0 : CERTVerifyLogNode *node = NULL;
914 [ # # ]: 0 : printChainFailure(&log);
915 : :
916 [ # # ]: 0 : for (node = log.head; node; node = node->next) {
917 [ # # ]: 0 : if (node->cert)
918 [ # # ]: 0 : CERT_DestroyCertificate(node->cert);
919 : : }
920 : 0 : log.head = log.tail = NULL;
921 : 0 : log.count = 0;
922 : : }
923 [ # # ]: 0 : xmlsec_trace("Certificate is invalid.\n");
924 : : }
925 : : }
926 : :
927 : : }
928 : : else
929 : : {
930 : 0 : validity = ::com::sun::star::security::CertificateValidity::INVALID ;
931 : : }
932 : :
933 : : //Destroying the temporary certificates
934 : 0 : std::vector<CERTCertificate*>::const_iterator cert_i;
935 [ # # ][ # # ]: 0 : for (cert_i = vecTmpNSSCertificates.begin(); cert_i != vecTmpNSSCertificates.end(); ++cert_i)
[ # # ]
936 : : {
937 [ # # ]: 0 : xmlsec_trace("Destroying temporary certificate");
938 [ # # ]: 0 : CERT_DestroyCertificate(*cert_i);
939 : : }
940 : 0 : return validity ;
941 : : }
942 : :
943 : 0 : sal_Int32 SecurityEnvironment_NssImpl::getCertificateCharacters(
944 : : const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) {
945 : : sal_Int32 characters ;
946 : : const X509Certificate_NssImpl* xcert ;
947 : : const CERTCertificate* cert ;
948 : :
949 [ # # ]: 0 : Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
950 [ # # ]: 0 : if( !xCertTunnel.is() ) {
951 [ # # ]: 0 : throw RuntimeException() ;
952 : : }
953 : :
954 : : xcert = reinterpret_cast<X509Certificate_NssImpl*>(
955 [ # # ][ # # ]: 0 : sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
[ # # ]
956 [ # # ]: 0 : if( xcert == NULL ) {
957 [ # # ]: 0 : throw RuntimeException() ;
958 : : }
959 : :
960 [ # # ]: 0 : cert = xcert->getNssCert() ;
961 : :
962 : 0 : characters = 0x00000000 ;
963 : :
964 : : //Firstly, find out whether or not the cert is self-signed.
965 [ # # ][ # # ]: 0 : if( SECITEM_CompareItem( &(cert->derIssuer), &(cert->derSubject) ) == SECEqual ) {
966 : 0 : characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
967 : : } else {
968 : 0 : characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
969 : : }
970 : :
971 : : //Secondly, find out whether or not the cert has a private key.
972 : :
973 : : /*
974 : : * i40394
975 : : *
976 : : * mmi : need to check whether the cert's slot is valid first
977 : : */
978 : 0 : SECKEYPrivateKey* priKey = NULL;
979 : :
980 [ # # ]: 0 : if (cert->slot != NULL)
981 : : {
982 [ # # ]: 0 : priKey = PK11_FindPrivateKeyFromCert( cert->slot, ( CERTCertificate* )cert, NULL ) ;
983 : : }
984 [ # # ]: 0 : if(priKey == NULL)
985 : : {
986 [ # # ]: 0 : for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
987 : : {
988 [ # # ]: 0 : priKey = PK11_FindPrivateKeyFromCert(*is, (CERTCertificate*)cert, NULL);
989 [ # # ]: 0 : if (priKey)
990 : 0 : break;
991 : : }
992 : : }
993 [ # # ]: 0 : if( priKey != NULL ) {
994 : 0 : characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
995 : :
996 [ # # ]: 0 : SECKEY_DestroyPrivateKey( priKey ) ;
997 : : } else {
998 : 0 : characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
999 : : }
1000 : :
1001 : 0 : return characters ;
1002 : : }
1003 : :
1004 : 0 : X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert )
1005 : : {
1006 : : X509Certificate_NssImpl* xcert ;
1007 : :
1008 [ # # ]: 0 : if( cert != NULL ) {
1009 [ # # ]: 0 : xcert = new X509Certificate_NssImpl() ;
1010 [ # # ]: 0 : if( xcert == NULL ) {
1011 : 0 : xcert = NULL ;
1012 : : } else {
1013 : 0 : xcert->setCert( cert ) ;
1014 : : }
1015 : : } else {
1016 : 0 : xcert = NULL ;
1017 : : }
1018 : :
1019 : 0 : return xcert ;
1020 : : }
1021 : :
1022 : 0 : X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* priKey )
1023 : : {
1024 : : CERTCertificate* cert ;
1025 : : X509Certificate_NssImpl* xcert ;
1026 : :
1027 [ # # ]: 0 : if( priKey != NULL ) {
1028 : 0 : cert = PK11_GetCertFromPrivateKey( priKey ) ;
1029 : :
1030 [ # # ]: 0 : if( cert != NULL ) {
1031 : 0 : xcert = NssCertToXCert( cert ) ;
1032 : : } else {
1033 : 0 : xcert = NULL ;
1034 : : }
1035 : :
1036 : 0 : CERT_DestroyCertificate( cert ) ;
1037 : : } else {
1038 : 0 : xcert = NULL ;
1039 : : }
1040 : :
1041 : 0 : return xcert ;
1042 : : }
1043 : :
1044 : :
1045 : : /* Native methods */
1046 : 0 : xmlSecKeysMngrPtr SecurityEnvironment_NssImpl::createKeysManager() throw( Exception, RuntimeException ) {
1047 : :
1048 : : unsigned int i ;
1049 : 0 : CERTCertDBHandle* handler = NULL ;
1050 : 0 : PK11SymKey* symKey = NULL ;
1051 : 0 : SECKEYPublicKey* pubKey = NULL ;
1052 : 0 : SECKEYPrivateKey* priKey = NULL ;
1053 : 0 : xmlSecKeysMngrPtr pKeysMngr = NULL ;
1054 : :
1055 [ # # ]: 0 : handler = this->getCertDb() ;
1056 : :
1057 : : /*-
1058 : : * The following lines is based on the private version of xmlSec-NSS
1059 : : * crypto engine
1060 : : */
1061 : 0 : int cSlots = m_Slots.size();
1062 [ # # ]: 0 : boost::scoped_array<PK11SlotInfo*> sarSlots(new PK11SlotInfo*[cSlots]);
1063 : 0 : PK11SlotInfo** slots = sarSlots.get();
1064 : 0 : int count = 0;
1065 [ # # ]: 0 : for (CIT_SLOTS islots = m_Slots.begin();islots != m_Slots.end(); islots++, count++)
1066 : 0 : slots[count] = *islots;
1067 : :
1068 [ # # ]: 0 : pKeysMngr = xmlSecNssAppliedKeysMngrCreate(slots, cSlots, handler ) ;
1069 [ # # ]: 0 : if( pKeysMngr == NULL )
1070 [ # # ]: 0 : throw RuntimeException() ;
1071 : :
1072 : : /*-
1073 : : * Adopt symmetric key into keys manager
1074 : : */
1075 [ # # ][ # # ]: 0 : for( i = 0 ; ( symKey = this->getSymKey( i ) ) != NULL ; i ++ ) {
1076 [ # # ][ # # ]: 0 : if( xmlSecNssAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
1077 [ # # ]: 0 : throw RuntimeException() ;
1078 : : }
1079 : : }
1080 : :
1081 : : /*-
1082 : : * Adopt asymmetric public key into keys manager
1083 : : */
1084 [ # # ][ # # ]: 0 : for( i = 0 ; ( pubKey = this->getPubKey( i ) ) != NULL ; i ++ ) {
1085 [ # # ][ # # ]: 0 : if( xmlSecNssAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
1086 [ # # ]: 0 : throw RuntimeException() ;
1087 : : }
1088 : : }
1089 : :
1090 : : /*-
1091 : : * Adopt asymmetric private key into keys manager
1092 : : */
1093 [ # # ][ # # ]: 0 : for( i = 0 ; ( priKey = this->getPriKey( i ) ) != NULL ; i ++ ) {
1094 [ # # ][ # # ]: 0 : if( xmlSecNssAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
1095 [ # # ]: 0 : throw RuntimeException() ;
1096 : : }
1097 : : }
1098 [ # # ]: 0 : return pKeysMngr ;
1099 : : }
1100 : 0 : void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
1101 [ # # ]: 0 : if( pKeysMngr != NULL ) {
1102 : 0 : xmlSecKeysMngrDestroy( pKeysMngr ) ;
1103 : : }
1104 : 0 : }
1105 : :
1106 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|