merged tag ooo/OOO330_m14
[LibreOffice.git] / xmlsecurity / source / xmlsec / mscrypt / securityenvironment_mscryptimpl.cxx
blob71ff13fb3f824b61de0d59a2564331a3d6b16dd8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #ifdef _MSC_VER
32 #pragma warning(push,1)
33 #endif
34 #include "Windows.h"
35 #include "WinCrypt.h"
36 #ifdef _MSC_VER
37 #pragma warning(pop)
38 #endif
39 #include <sal/config.h>
40 #include <osl/thread.h>
41 #include "securityenvironment_mscryptimpl.hxx"
43 #ifndef _X509CERTIFICATE_NSSIMPL_HXX_
44 #include "x509certificate_mscryptimpl.hxx"
45 #endif
46 #include <rtl/uuid.h>
48 #include <xmlsec/xmlsec.h>
49 #include <xmlsec/keysmngr.h>
50 #include <xmlsec/crypto.h>
51 #include <xmlsec/base64.h>
53 #include <xmlsecurity/biginteger.hxx>
55 #include "xmlsec/keysmngr.h"
56 #include "xmlsec/mscrypto/akmngr.h"
58 //CP : added by CP
59 #include <rtl/locale.h>
60 #include <osl/nlsupport.h>
61 #include <osl/process.h>
63 //CP : end
64 #include <rtl/memory.h>
66 #include "../diagnose.hxx"
68 using namespace xmlsecurity;
69 using namespace ::com::sun::star::uno ;
70 using namespace ::com::sun::star::lang ;
71 using ::com::sun::star::lang::XMultiServiceFactory ;
72 using ::com::sun::star::lang::XSingleServiceFactory ;
73 using ::rtl::OUString ;
75 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
76 using ::com::sun::star::security::XCertificate ;
77 namespace css = ::com::sun::star;
79 extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ;
81 struct CertErrorToString{
82 DWORD error;
83 char * name;
86 CertErrorToString arErrStrings[] =
88 { 0x00000000, "CERT_TRUST_NO_ERROR"},
89 { 0x00000001, "CERT_TRUST_IS_NOT_TIME_VALID"},
90 { 0x00000002, "CERT_TRUST_IS_NOT_TIME_NESTED"},
91 { 0x00000004, "CERT_TRUST_IS_REVOKED" },
92 { 0x00000008, "CERT_TRUST_IS_NOT_SIGNATURE_VALID" },
93 { 0x00000010, "CERT_TRUST_IS_NOT_SIGNATURE_VALID"},
94 { 0x00000020, "CERT_TRUST_IS_UNTRUSTED_ROOT"},
95 { 0x00000040, "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"},
96 { 0x00000080, "CERT_TRUST_IS_CYCLIC"},
97 { 0x00000100, "CERT_TRUST_INVALID_EXTENSION"},
98 { 0x00000200, "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"},
99 { 0x00000400, "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"},
100 { 0x00000800, "CERT_TRUST_INVALID_NAME_CONSTRAINTS"},
101 { 0x00001000, "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"},
102 { 0x00002000, "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"},
103 { 0x00004000, "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"},
104 { 0x00008000, "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"},
105 { 0x01000000, "CERT_TRUST_IS_OFFLINE_REVOCATION"},
106 { 0x02000000, "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"},
107 { 0x04000000, "CERT_TRUST_IS_EXPLICIT_DISTRUST"},
108 { 0x08000000, "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"},
109 //Chain errors
110 { 0x00010000, "CERT_TRUST_IS_PARTIAL_CHAIN"},
111 { 0x00020000, "CERT_TRUST_CTL_IS_NOT_TIME_VALID"},
112 { 0x00040000, "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"},
113 { 0x00080000, "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"}
116 void traceTrustStatus(DWORD err)
118 int numErrors = sizeof(arErrStrings) / sizeof(CertErrorToString);
119 xmlsec_trace("The certificate error status is: ");
120 if (err == 0)
121 xmlsec_trace("%s", arErrStrings[0].name);
122 for (int i = 1; i < numErrors; i++)
124 if (arErrStrings[i].error & err)
125 xmlsec_trace("%s", arErrStrings[i].name);
129 SecurityEnvironment_MSCryptImpl :: SecurityEnvironment_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_hProv( NULL ) , m_pszContainer( NULL ) , m_hKeyStore( NULL ), m_hCertStore( NULL ), m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList(), m_xServiceManager( aFactory ), m_bEnableDefault( sal_False ) {
133 SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() {
135 if( m_hProv != NULL ) {
136 CryptReleaseContext( m_hProv, 0 ) ;
137 m_hProv = NULL ;
140 if( m_pszContainer != NULL ) {
141 //TODO: Don't know whether or not it should be released now.
142 m_pszContainer = NULL ;
145 if( m_hCertStore != NULL ) {
146 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
147 m_hCertStore = NULL ;
150 if( m_hKeyStore != NULL ) {
151 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
152 m_hKeyStore = NULL ;
155 if( !m_tSymKeyList.empty() ) {
156 std::list< HCRYPTKEY >::iterator symKeyIt ;
158 for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ )
159 CryptDestroyKey( *symKeyIt ) ;
162 if( !m_tPubKeyList.empty() ) {
163 std::list< HCRYPTKEY >::iterator pubKeyIt ;
165 for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ )
166 CryptDestroyKey( *pubKeyIt ) ;
169 if( !m_tPriKeyList.empty() ) {
170 std::list< HCRYPTKEY >::iterator priKeyIt ;
172 for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ )
173 CryptDestroyKey( *priKeyIt ) ;
178 /* XInitialization */
179 void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
180 //TODO
183 /* XServiceInfo */
184 OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
185 return impl_getImplementationName() ;
188 /* XServiceInfo */
189 sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
190 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
191 const OUString* pArray = seqServiceNames.getConstArray() ;
192 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
193 if( *( pArray + i ) == serviceName )
194 return sal_True ;
196 return sal_False ;
199 /* XServiceInfo */
200 Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
201 return impl_getSupportedServiceNames() ;
204 //Helper for XServiceInfo
205 Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() {
206 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
207 Sequence< OUString > seqServiceNames( 1 ) ;
208 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ;
209 return seqServiceNames ;
212 OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
213 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ;
216 //Helper for registry
217 Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
218 return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ;
221 Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
222 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
225 /* XUnoTunnel */
226 sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
227 throw( RuntimeException )
229 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
230 return ( sal_Int64 )this ;
232 return 0 ;
235 /* XUnoTunnel extension */
236 const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() {
237 static Sequence< sal_Int8 >* pSeq = 0 ;
238 if( !pSeq ) {
239 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
240 if( !pSeq ) {
241 static Sequence< sal_Int8> aSeq( 16 ) ;
242 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
243 pSeq = &aSeq ;
246 return *pSeq ;
249 /* XUnoTunnel extension */
250 SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
251 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
252 if( xUT.is() ) {
253 return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
254 } else
255 return NULL ;
258 /* Native methods */
259 HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
260 return m_hProv ;
263 void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
264 if( m_hProv != NULL ) {
265 CryptReleaseContext( m_hProv, 0 ) ;
266 m_hProv = NULL ;
269 if( aProv != NULL ) {
270 /*- Replaced by direct adopt for WINNT support ----
271 if( !CryptContextAddRef( aProv, NULL, NULL ) )
272 throw Exception() ;
273 else
274 m_hProv = aProv ;
275 ----*/
276 m_hProv = aProv ;
280 LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
281 return m_pszContainer ;
284 void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
285 //TODO: Don't know whether or not it should be copied.
286 m_pszContainer = aKeyContainer ;
290 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) {
291 return m_hKeyStore ;
294 void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) {
295 if( m_hKeyStore != NULL ) {
296 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
297 m_hKeyStore = NULL ;
300 if( aSlot != NULL ) {
301 m_hKeyStore = CertDuplicateStore( aSlot ) ;
305 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) {
306 return m_hCertStore ;
309 void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) {
310 if( m_hCertStore != NULL ) {
311 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
312 m_hCertStore = NULL ;
315 if( aCertDb != NULL ) {
316 m_hCertStore = CertDuplicateStore( aCertDb ) ;
320 void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
321 HCRYPTKEY symkey ;
322 std::list< HCRYPTKEY >::iterator keyIt ;
324 if( aSymKey != NULL ) {
325 //First try to find the key in the list
326 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
327 if( *keyIt == aSymKey )
328 return ;
331 //If we do not find the key in the list, add a new node
332 /*- Replaced with directly adopt for WINNT 4.0 support ----
333 if( !CryptDuplicateKey( aSymKey, NULL, 0, &symkey ) )
334 throw RuntimeException() ;
335 ----*/
336 symkey = aSymKey ;
338 try {
339 m_tSymKeyList.push_back( symkey ) ;
340 } catch ( Exception& ) {
341 CryptDestroyKey( symkey ) ;
346 void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
347 HCRYPTKEY symkey ;
348 std::list< HCRYPTKEY >::iterator keyIt ;
350 if( aSymKey != NULL ) {
351 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
352 if( *keyIt == aSymKey ) {
353 symkey = *keyIt ;
354 CryptDestroyKey( symkey ) ;
355 m_tSymKeyList.erase( keyIt ) ;
356 break ;
362 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
363 HCRYPTKEY symkey ;
364 std::list< HCRYPTKEY >::iterator keyIt ;
365 unsigned int pos ;
367 symkey = NULL ;
368 for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
370 if( pos == position && keyIt != m_tSymKeyList.end() )
371 symkey = *keyIt ;
373 return symkey ;
376 void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
377 HCRYPTKEY pubkey ;
378 std::list< HCRYPTKEY >::iterator keyIt ;
380 if( aPubKey != NULL ) {
381 //First try to find the key in the list
382 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
383 if( *keyIt == aPubKey )
384 return ;
387 //If we do not find the key in the list, add a new node
388 /*- Replaced with directly adopt for WINNT 4.0 support ----
389 if( !CryptDuplicateKey( aPubKey, NULL, 0, &pubkey ) )
390 throw RuntimeException() ;
391 ----*/
392 pubkey = aPubKey ;
394 try {
395 m_tPubKeyList.push_back( pubkey ) ;
396 } catch ( Exception& ) {
397 CryptDestroyKey( pubkey ) ;
402 void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
403 HCRYPTKEY pubkey ;
404 std::list< HCRYPTKEY >::iterator keyIt ;
406 if( aPubKey != NULL ) {
407 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
408 if( *keyIt == aPubKey ) {
409 pubkey = *keyIt ;
410 CryptDestroyKey( pubkey ) ;
411 m_tPubKeyList.erase( keyIt ) ;
412 break ;
418 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
419 HCRYPTKEY pubkey ;
420 std::list< HCRYPTKEY >::iterator keyIt ;
421 unsigned int pos ;
423 pubkey = NULL ;
424 for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
426 if( pos == position && keyIt != m_tPubKeyList.end() )
427 pubkey = *keyIt ;
429 return pubkey ;
432 void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
433 HCRYPTKEY prikey ;
434 std::list< HCRYPTKEY >::iterator keyIt ;
436 if( aPriKey != NULL ) {
437 //First try to find the key in the list
438 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
439 if( *keyIt == aPriKey )
440 return ;
443 //If we do not find the key in the list, add a new node
444 /*- Replaced with directly adopt for WINNT 4.0 support ----
445 if( !CryptDuplicateKey( aPriKey, NULL, 0, &prikey ) )
446 throw RuntimeException() ;
447 ----*/
448 prikey = aPriKey ;
450 try {
451 m_tPriKeyList.push_back( prikey ) ;
452 } catch ( Exception& ) {
453 CryptDestroyKey( prikey ) ;
458 void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
459 HCRYPTKEY prikey ;
460 std::list< HCRYPTKEY >::iterator keyIt ;
462 if( aPriKey != NULL ) {
463 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
464 if( *keyIt == aPriKey ) {
465 prikey = *keyIt ;
466 CryptDestroyKey( prikey ) ;
467 m_tPriKeyList.erase( keyIt ) ;
468 break ;
474 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) {
475 HCRYPTKEY prikey ;
476 std::list< HCRYPTKEY >::iterator keyIt ;
477 unsigned int pos ;
479 prikey = NULL ;
480 for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
482 if( pos == position && keyIt != m_tPriKeyList.end() )
483 prikey = *keyIt ;
485 return prikey ;
488 //Methods from XSecurityEnvironment
489 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException )
491 sal_Int32 length ;
492 X509Certificate_MSCryptImpl* xcert ;
493 std::list< X509Certificate_MSCryptImpl* > certsList ;
494 PCCERT_CONTEXT pCertContext = NULL;
496 //firstly, we try to find private keys in given key store.
497 if( m_hKeyStore != NULL ) {
498 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
499 while (pCertContext)
501 xcert = MswcryCertContextToXCert( pCertContext ) ;
502 if( xcert != NULL )
503 certsList.push_back( xcert ) ;
504 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
508 //secondly, we try to find certificate from registered private keys.
509 if( !m_tPriKeyList.empty() ) {
510 //TODO: Don't know whether or not it is necessary ans possible.
513 //Thirdly, we try to find certificate from system default key store.
514 if( m_bEnableDefault ) {
515 HCERTSTORE hSystemKeyStore ;
516 DWORD dwKeySpec;
517 HCRYPTPROV hCryptProv;
520 hSystemKeyStore = CertOpenStore(
521 CERT_STORE_PROV_SYSTEM ,
523 NULL ,
524 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG ,
525 L"MY"
528 hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ;
529 if( hSystemKeyStore != NULL ) {
530 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
531 while (pCertContext)
533 // Add By CP for checking whether the certificate is a personal certificate or not.
534 if(!(CryptAcquireCertificatePrivateKey(pCertContext,
535 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
536 NULL,
537 &hCryptProv,
538 &dwKeySpec,
539 NULL)))
541 // Not Privatekey found. SKIP this one; By CP
542 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
543 continue;
545 // then TODO : Check the personal cert is valid or not.
547 // end CP
548 xcert = MswcryCertContextToXCert( pCertContext ) ;
549 if( xcert != NULL )
550 certsList.push_back( xcert ) ;
551 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
555 CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
558 length = certsList.size() ;
559 if( length != 0 ) {
560 int i ;
561 std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ;
562 Sequence< Reference< XCertificate > > certSeq( length ) ;
564 for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) {
565 certSeq[i] = *xcertIt ;
568 return certSeq ;
571 return Sequence< Reference< XCertificate > >() ;
575 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) {
576 unsigned int i ;
577 // sal_Int8 found = 0 ;
578 LPSTR pszName ;
579 X509Certificate_MSCryptImpl *xcert = NULL ;
580 PCCERT_CONTEXT pCertContext = NULL ;
581 HCERTSTORE hCertStore = NULL ;
582 CRYPT_INTEGER_BLOB cryptSerialNumber ;
583 CERT_INFO certInfo ;
585 // By CP , for correct encoding
586 sal_uInt16 encoding ;
587 rtl_Locale *pLocale = NULL ;
588 osl_getProcessLocale( &pLocale ) ;
589 encoding = osl_getTextEncodingFromLocale( pLocale ) ;
590 // CP end
592 //Create cert info from issue and serial
593 rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ;
594 pszName = ( char* )oissuer.getStr() ;
596 if( ! ( CertStrToName(
597 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
598 pszName ,
599 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
600 NULL ,
601 NULL ,
602 &certInfo.Issuer.cbData, NULL ) )
604 return NULL ;
607 certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData );
608 if(!certInfo.Issuer.pbData)
609 throw RuntimeException() ;
611 if( ! ( CertStrToName(
612 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
613 pszName ,
614 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
615 NULL ,
616 ( BYTE* )certInfo.Issuer.pbData ,
617 &certInfo.Issuer.cbData, NULL ) )
619 free( certInfo.Issuer.pbData ) ;
620 return NULL ;
623 //Get the SerialNumber
624 cryptSerialNumber.cbData = serialNumber.getLength() ;
625 cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData);
626 if (!cryptSerialNumber.pbData)
628 free( certInfo.Issuer.pbData ) ;
629 throw RuntimeException() ;
631 for( i = 0; i < cryptSerialNumber.cbData; i ++ )
632 cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ;
634 certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ;
635 certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ;
637 // Get the Cert from all store.
638 for( i = 0 ; i < 6 ; i ++ )
640 switch(i)
642 case 0:
643 if(m_hKeyStore == NULL) continue ;
644 hCertStore = m_hKeyStore ;
645 break;
646 case 1:
647 if(m_hCertStore == NULL) continue ;
648 hCertStore = m_hCertStore ;
649 break;
650 case 2:
651 hCertStore = CertOpenSystemStore( 0, "MY" ) ;
652 if(hCertStore == NULL || !m_bEnableDefault) continue ;
653 break;
654 case 3:
655 hCertStore = CertOpenSystemStore( 0, "Root" ) ;
656 if(hCertStore == NULL || !m_bEnableDefault) continue ;
657 break;
658 case 4:
659 hCertStore = CertOpenSystemStore( 0, "Trust" ) ;
660 if(hCertStore == NULL || !m_bEnableDefault) continue ;
661 break;
662 case 5:
663 hCertStore = CertOpenSystemStore( 0, "CA" ) ;
664 if(hCertStore == NULL || !m_bEnableDefault) continue ;
665 break;
666 default:
667 i=6;
668 continue;
671 /*******************************************************************************
672 * This code reserved for remind us there are another way to find one cert by
673 * IssuerName&serialnumber. You can use the code to replaced the function
674 * CertFindCertificateInStore IF and ONLY IF you must find one special cert in
675 * certStore but can not be found by CertFindCertificateInStore , then , you
676 * should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875.
677 * By Chandler Peng(chandler.peng@sun.com)
678 *****/
679 /*******************************************************************************
680 pCertContext = NULL ;
681 found = 0;
683 // 1. enum the certs has same string in the issuer string.
684 pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ;
685 if( pCertContext != NULL )
687 // 2. check the cert's issuer name .
688 char* issuer = NULL ;
689 DWORD cbIssuer = 0 ;
691 cbIssuer = CertNameToStr(
692 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
693 &( pCertContext->pCertInfo->Issuer ),
694 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
695 NULL, 0
698 if( cbIssuer == 0 ) continue ; // discard this cert;
700 issuer = (char *)malloc( cbIssuer ) ;
701 if( issuer == NULL ) // discard this cert;
703 free( cryptSerialNumber.pbData) ;
704 free( certInfo.Issuer.pbData ) ;
705 CertFreeCertificateContext( pCertContext ) ;
706 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
707 throw RuntimeException() ;
710 cbIssuer = CertNameToStr(
711 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
712 &( pCertContext->pCertInfo->Issuer ),
713 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
714 issuer, cbIssuer
717 if( cbIssuer <= 0 )
719 free( issuer ) ;
720 continue ;// discard this cert;
723 if(strncmp(pszName , issuer , cbIssuer) != 0)
725 free( issuer ) ;
726 continue ;// discard this cert;
728 free( issuer ) ;
730 // 3. check the serial number.
731 if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 )
733 continue ;// discard this cert;
736 // 4. confirm and break;
737 found = 1;
738 break ;
741 }while(pCertContext);
743 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
744 if( found != 0 ) break; // Found the certificate.
745 ********************************************************************************/
747 pCertContext = CertFindCertificateInStore(
748 hCertStore,
749 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
751 CERT_FIND_SUBJECT_CERT,
752 &certInfo,
753 NULL
756 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
757 if( pCertContext != NULL ) break ; // Found the certificate.
761 if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ;
762 if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ;
764 if( pCertContext != NULL ) {
765 xcert = MswcryCertContextToXCert( pCertContext ) ;
766 if( pCertContext ) CertFreeCertificateContext( pCertContext ) ;
767 } else {
768 xcert = NULL ;
771 return xcert ;
774 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
775 Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
776 return getCertificate( issuerName, serial ) ;
779 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
780 PCCERT_CHAIN_CONTEXT pChainContext ;
781 PCCERT_CONTEXT pCertContext ;
782 const X509Certificate_MSCryptImpl* xcert ;
784 CERT_ENHKEY_USAGE enhKeyUsage ;
785 CERT_USAGE_MATCH certUsage ;
786 CERT_CHAIN_PARA chainPara ;
788 enhKeyUsage.cUsageIdentifier = 0 ;
789 enhKeyUsage.rgpszUsageIdentifier = NULL ;
790 certUsage.dwType = USAGE_MATCH_TYPE_AND ;
791 certUsage.Usage = enhKeyUsage ;
792 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
793 chainPara.RequestedUsage = certUsage ;
795 Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
796 if( !xCertTunnel.is() ) {
797 throw RuntimeException() ;
800 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
801 if( xcert == NULL ) {
802 throw RuntimeException() ;
805 pCertContext = xcert->getMswcryCert() ;
807 pChainContext = NULL ;
809 BOOL bChain = FALSE;
810 if( pCertContext != NULL )
812 HCERTSTORE hAdditionalStore = NULL;
813 HCERTSTORE hCollectionStore = NULL;
814 if (m_hCertStore && m_hKeyStore)
816 //Merge m_hCertStore and m_hKeyStore into one store.
817 hCollectionStore = CertOpenStore(
818 CERT_STORE_PROV_COLLECTION ,
820 NULL ,
822 NULL
824 if (hCollectionStore != NULL)
826 CertAddStoreToCollection (
827 hCollectionStore ,
828 m_hCertStore ,
829 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
830 0) ;
831 CertAddStoreToCollection (
832 hCollectionStore ,
833 m_hCertStore ,
834 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
835 0) ;
836 hAdditionalStore = hCollectionStore;
841 //if the merge of both stores failed then we add only m_hCertStore
842 if (hAdditionalStore == NULL && m_hCertStore)
843 hAdditionalStore = m_hCertStore;
844 else if (hAdditionalStore == NULL && m_hKeyStore)
845 hAdditionalStore = m_hKeyStore;
846 else
847 hAdditionalStore = NULL;
849 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
850 bChain = CertGetCertificateChain(
851 NULL ,
852 pCertContext ,
853 NULL , //use current system time
854 hAdditionalStore,
855 &chainPara ,
856 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
857 NULL ,
858 &pChainContext);
859 if (!bChain)
860 pChainContext = NULL;
862 //Close the additional store
863 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
866 if(bChain && pChainContext != NULL && pChainContext->cChain > 0 )
868 PCCERT_CONTEXT pCertInChain ;
869 PCERT_SIMPLE_CHAIN pCertChain ;
870 X509Certificate_MSCryptImpl* pCert ;
872 pCertChain = pChainContext->rgpChain[0] ;
873 if( pCertChain->cElement ) {
874 Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ;
876 for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) {
877 if( pCertChain->rgpElement[i] )
878 pCertInChain = pCertChain->rgpElement[i]->pCertContext ;
879 else
880 pCertInChain = NULL ;
882 if( pCertInChain != NULL ) {
883 pCert = MswcryCertContextToXCert( pCertInChain ) ;
884 if( pCert != NULL )
885 xCertChain[i] = pCert ;
889 CertFreeCertificateChain( pChainContext ) ;
890 pChainContext = NULL ;
892 return xCertChain ;
895 if (pChainContext)
896 CertFreeCertificateChain(pChainContext);
898 return NULL ;
901 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
902 X509Certificate_MSCryptImpl* xcert ;
904 if( rawCertificate.getLength() > 0 ) {
905 xcert = new X509Certificate_MSCryptImpl() ;
906 if( xcert == NULL )
907 throw RuntimeException() ;
909 xcert->setRawCert( rawCertificate ) ;
910 } else {
911 xcert = NULL ;
914 return xcert ;
917 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
918 xmlChar* chCert ;
919 xmlSecSize certSize ;
921 rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
923 chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
925 certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
927 Sequence< sal_Int8 > rawCert( certSize ) ;
928 for( unsigned int i = 0 ; i < certSize ; i ++ )
929 rawCert[i] = *( chCert + i ) ;
931 xmlFree( chCert ) ;
933 return createCertificateFromRaw( rawCert ) ;
937 HCERTSTORE getCertStoreForIntermediatCerts(
938 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
940 HCERTSTORE store = NULL;
941 store = CertOpenStore(
942 CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
943 if (store == NULL)
944 return NULL;
946 for (int i = 0; i < seqCerts.getLength(); i++)
948 xmlsec_trace("Added temporary certificate: \n%s",
949 OUStringToOString(seqCerts[i]->getSubjectName(),
950 osl_getThreadTextEncoding()).getStr());
953 Sequence<sal_Int8> data = seqCerts[i]->getEncoded();
954 PCCERT_CONTEXT cert = CertCreateCertificateContext(
955 X509_ASN_ENCODING, ( const BYTE* )&data[0], data.getLength());
956 //Adding the certificate creates a copy and not just increases the ref count
957 //Therefore we free later the certificate that we now add
958 CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, NULL);
959 CertFreeCertificateContext(cert);
961 return store;
964 //We return only valid or invalid, as long as the API documentation expresses
965 //explicitly that all validation steps are carried out even if one or several
966 //errors occur. See also
967 //http://wiki.services.openoffice.org/wiki/Certificate_Path_Validation#Validation_status
968 sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate(
969 const Reference< ::com::sun::star::security::XCertificate >& aCert,
970 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
971 throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException )
973 sal_Int32 validity = 0;
974 PCCERT_CHAIN_CONTEXT pChainContext = NULL;
975 PCCERT_CONTEXT pCertContext = NULL;
976 const X509Certificate_MSCryptImpl* xcert = NULL;
978 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
979 if( !xCertTunnel.is() ) {
980 throw RuntimeException() ;
983 xmlsec_trace("Start verification of certificate: \n %s",
984 OUStringToOString(
985 aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr());
987 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
988 if( xcert == NULL ) {
989 throw RuntimeException() ;
992 pCertContext = xcert->getMswcryCert() ;
994 CERT_ENHKEY_USAGE enhKeyUsage ;
995 CERT_USAGE_MATCH certUsage ;
996 CERT_CHAIN_PARA chainPara ;
997 rtl_zeroMemory(&chainPara, sizeof(CERT_CHAIN_PARA));
999 //Prepare parameter for CertGetCertificateChain
1000 enhKeyUsage.cUsageIdentifier = 0 ;
1001 enhKeyUsage.rgpszUsageIdentifier = NULL ;
1002 certUsage.dwType = USAGE_MATCH_TYPE_AND ;
1003 certUsage.Usage = enhKeyUsage ;
1004 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
1005 chainPara.RequestedUsage = certUsage ;
1008 HCERTSTORE hCollectionStore = NULL;
1009 HCERTSTORE hIntermediateCertsStore = NULL;
1010 BOOL bChain = FALSE;
1011 if( pCertContext != NULL )
1013 hIntermediateCertsStore =
1014 getCertStoreForIntermediatCerts(seqCerts);
1016 //Merge m_hCertStore and m_hKeyStore and the store of the intermediate
1017 //certificates into one store.
1018 hCollectionStore = CertOpenStore(
1019 CERT_STORE_PROV_COLLECTION ,
1021 NULL ,
1023 NULL
1025 if (hCollectionStore != NULL)
1027 CertAddStoreToCollection (
1028 hCollectionStore ,
1029 m_hCertStore ,
1030 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
1031 0) ;
1032 CertAddStoreToCollection (
1033 hCollectionStore ,
1034 m_hCertStore ,
1035 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
1036 0) ;
1037 CertAddStoreToCollection (
1038 hCollectionStore,
1039 hIntermediateCertsStore,
1040 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
1045 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
1046 //We do not check revocation of the root. In most cases there are none.
1047 //Then we would get CERT_TRUST_REVOCATION_STATUS_UNKNOWN
1048 xmlsec_trace("Verifying cert using revocation information.");
1049 bChain = CertGetCertificateChain(
1050 NULL ,
1051 pCertContext ,
1052 NULL , //use current system time
1053 hCollectionStore,
1054 &chainPara ,
1055 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
1056 NULL ,
1057 &pChainContext);
1059 if (bChain && pChainContext->cChain > 0)
1061 xmlsec_trace("Overall error status (all chains):");
1062 traceTrustStatus(pChainContext->TrustStatus.dwErrorStatus);
1063 //highest quality chains come first
1064 PCERT_SIMPLE_CHAIN pSimpleChain = pChainContext->rgpChain[0];
1065 xmlsec_trace("Error status of first chain: ");
1066 traceTrustStatus(pSimpleChain->TrustStatus.dwErrorStatus);
1068 //CERT_TRUST_REVOCATION_STATUS_UNKNOWN is also set if a certificate
1069 //has no AIA(OCSP) or CRLDP extension and there is no CRL locally installed.
1070 DWORD revocationFlags = CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
1071 CERT_TRUST_IS_OFFLINE_REVOCATION;
1072 DWORD otherErrorsMask = ~revocationFlags;
1073 if( !(pSimpleChain->TrustStatus.dwErrorStatus & otherErrorsMask))
1076 //No errors except maybe those caused by missing revocation information
1077 //Check if there are errors
1078 if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags)
1080 //No revocation information. Because MSDN documentation is not
1081 //clear about if all other tests are performed if an error occurrs,
1082 //we test again, without requiring revocation checking.
1083 CertFreeCertificateChain(pChainContext);
1084 pChainContext = NULL;
1085 xmlsec_trace("Checking again but without requiring revocation information.");
1086 bChain = CertGetCertificateChain(
1087 NULL ,
1088 pCertContext ,
1089 NULL , //use current system time
1090 hCollectionStore,
1091 &chainPara ,
1093 NULL ,
1094 &pChainContext);
1095 if (bChain
1096 && pChainContext->cChain > 0
1097 && pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
1099 xmlsec_trace("Certificate is valid.\n");
1100 validity = ::com::sun::star::security::CertificateValidity::VALID;
1102 else
1104 xmlsec_trace("Certificate is invalid.\n");
1107 else
1109 //valid and revocation information available
1110 xmlsec_trace("Certificate is valid.\n");
1111 validity = ::com::sun::star::security::CertificateValidity::VALID;
1114 else
1116 //invalid
1117 xmlsec_trace("Certificate is invalid.\n");
1118 validity = ::com::sun::star::security::CertificateValidity::INVALID ;
1121 else
1123 xmlsec_trace("CertGetCertificateChaine failed.\n");
1127 if (pChainContext)
1129 CertFreeCertificateChain(pChainContext);
1130 pChainContext = NULL;
1133 //Close the additional store, do not destroy the contained certs
1134 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
1135 //Close the temporary store containing the intermediate certificates and make
1136 //sure all certificates are deleted.
1137 CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG);
1139 return validity ;
1142 sal_Int32 SecurityEnvironment_MSCryptImpl :: getCertificateCharacters( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) {
1143 sal_Int32 characters ;
1144 PCCERT_CONTEXT pCertContext ;
1145 const X509Certificate_MSCryptImpl* xcert ;
1147 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
1148 if( !xCertTunnel.is() ) {
1149 throw RuntimeException() ;
1152 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
1153 if( xcert == NULL ) {
1154 throw RuntimeException() ;
1157 pCertContext = xcert->getMswcryCert() ;
1159 characters = 0x00000000 ;
1161 //Firstly, make sentence whether or not the cert is self-signed.
1162 if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) {
1163 characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1164 } else {
1165 characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1168 //Secondly, make sentence whether or not the cert has a private key.
1170 BOOL fCallerFreeProv ;
1171 DWORD dwKeySpec ;
1172 HCRYPTPROV hProv ;
1173 if( CryptAcquireCertificatePrivateKey( pCertContext ,
1175 NULL ,
1176 &( hProv ) ,
1177 &( dwKeySpec ) ,
1178 &( fCallerFreeProv ) )
1180 characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1182 if( hProv != NULL && fCallerFreeProv )
1183 CryptReleaseContext( hProv, 0 ) ;
1184 } else {
1185 characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1188 return characters ;
1191 void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) {
1192 m_bEnableDefault = enable ;
1195 sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) {
1196 return m_bEnableDefault ;
1199 X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert )
1201 X509Certificate_MSCryptImpl* xcert ;
1203 if( cert != NULL ) {
1204 xcert = new X509Certificate_MSCryptImpl() ;
1205 if( xcert != NULL ) {
1206 xcert->setMswcryCert( cert ) ;
1208 } else {
1209 xcert = NULL ;
1212 return xcert ;
1215 ::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
1217 return rtl::OUString::createFromAscii("Microsoft Crypto API");
1220 /* Native methods */
1221 xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) {
1223 unsigned int i ;
1224 HCRYPTKEY symKey ;
1225 HCRYPTKEY pubKey ;
1226 HCRYPTKEY priKey ;
1227 xmlSecKeysMngrPtr pKeysMngr = NULL ;
1230 * The following lines is based on the of xmlsec-mscrypto crypto engine
1232 pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ;
1233 if( pKeysMngr == NULL )
1234 throw RuntimeException() ;
1237 * Adopt symmetric key into keys manager
1239 for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) {
1240 if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
1241 throw RuntimeException() ;
1246 * Adopt asymmetric public key into keys manager
1248 for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) {
1249 if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
1250 throw RuntimeException() ;
1255 * Adopt asymmetric private key into keys manager
1257 for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) {
1258 if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
1259 throw RuntimeException() ;
1264 * Adopt system default certificate store.
1266 if( defaultEnabled() ) {
1267 HCERTSTORE hSystemStore ;
1269 //Add system key store into the keys manager.
1270 hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
1271 if( hSystemStore != NULL ) {
1272 if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, hSystemStore ) < 0 ) {
1273 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1274 throw RuntimeException() ;
1278 //Add system root store into the keys manager.
1279 hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
1280 if( hSystemStore != NULL ) {
1281 if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1282 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1283 throw RuntimeException() ;
1287 //Add system trusted store into the keys manager.
1288 hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
1289 if( hSystemStore != NULL ) {
1290 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1291 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1292 throw RuntimeException() ;
1296 //Add system CA store into the keys manager.
1297 hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
1298 if( hSystemStore != NULL ) {
1299 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1300 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1301 throw RuntimeException() ;
1306 return pKeysMngr ;
1308 void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
1309 if( pKeysMngr != NULL ) {
1310 xmlSecKeysMngrDestroy( pKeysMngr ) ;