Update ooo320-m1
[ooovba.git] / xmlsecurity / source / xmlsec / mscrypt / securityenvironment_mscryptimpl.cxx
blob3e06a89b3a7951ae886a75f28ee5084e9b2d49a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: securityenvironment_mscryptimpl.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #ifdef _MSC_VER
35 #pragma warning(push,1)
36 #endif
37 #include "Windows.h"
38 #include "WinCrypt.h"
39 #ifdef _MSC_VER
40 #pragma warning(pop)
41 #endif
42 #include <sal/config.h>
43 #include "securityenvironment_mscryptimpl.hxx"
45 #ifndef _X509CERTIFICATE_NSSIMPL_HXX_
46 #include "x509certificate_mscryptimpl.hxx"
47 #endif
48 #include <rtl/uuid.h>
50 #include <xmlsec/xmlsec.h>
51 #include <xmlsec/keysmngr.h>
52 #include <xmlsec/crypto.h>
53 #include <xmlsec/base64.h>
55 #include <xmlsecurity/biginteger.hxx>
57 #include "xmlsec/keysmngr.h"
58 #include "xmlsec/mscrypto/akmngr.h"
60 //CP : added by CP
61 #include <rtl/locale.h>
62 #include <osl/nlsupport.h>
63 #include <osl/process.h>
65 //CP : end
67 using namespace ::com::sun::star::uno ;
68 using namespace ::com::sun::star::lang ;
69 using ::com::sun::star::lang::XMultiServiceFactory ;
70 using ::com::sun::star::lang::XSingleServiceFactory ;
71 using ::rtl::OUString ;
73 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
74 using ::com::sun::star::security::XCertificate ;
76 extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ;
78 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 ) {
82 SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() {
84 if( m_hProv != NULL ) {
85 CryptReleaseContext( m_hProv, 0 ) ;
86 m_hProv = NULL ;
89 if( m_pszContainer != NULL ) {
90 //TODO: Don't know whether or not it should be released now.
91 m_pszContainer = NULL ;
94 if( m_hCertStore != NULL ) {
95 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
96 m_hCertStore = NULL ;
99 if( m_hKeyStore != NULL ) {
100 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
101 m_hKeyStore = NULL ;
104 if( !m_tSymKeyList.empty() ) {
105 std::list< HCRYPTKEY >::iterator symKeyIt ;
107 for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ )
108 CryptDestroyKey( *symKeyIt ) ;
111 if( !m_tPubKeyList.empty() ) {
112 std::list< HCRYPTKEY >::iterator pubKeyIt ;
114 for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ )
115 CryptDestroyKey( *pubKeyIt ) ;
118 if( !m_tPriKeyList.empty() ) {
119 std::list< HCRYPTKEY >::iterator priKeyIt ;
121 for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ )
122 CryptDestroyKey( *priKeyIt ) ;
127 /* XInitialization */
128 void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
129 //TODO
132 /* XServiceInfo */
133 OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
134 return impl_getImplementationName() ;
137 /* XServiceInfo */
138 sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
139 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
140 const OUString* pArray = seqServiceNames.getConstArray() ;
141 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
142 if( *( pArray + i ) == serviceName )
143 return sal_True ;
145 return sal_False ;
148 /* XServiceInfo */
149 Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
150 return impl_getSupportedServiceNames() ;
153 //Helper for XServiceInfo
154 Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() {
155 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
156 Sequence< OUString > seqServiceNames( 1 ) ;
157 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ;
158 return seqServiceNames ;
161 OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
162 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ;
165 //Helper for registry
166 Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
167 return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ;
170 Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
171 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
174 /* XUnoTunnel */
175 sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
176 throw( RuntimeException )
178 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
179 return ( sal_Int64 )this ;
181 return 0 ;
184 /* XUnoTunnel extension */
185 const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() {
186 static Sequence< sal_Int8 >* pSeq = 0 ;
187 if( !pSeq ) {
188 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
189 if( !pSeq ) {
190 static Sequence< sal_Int8> aSeq( 16 ) ;
191 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
192 pSeq = &aSeq ;
195 return *pSeq ;
198 /* XUnoTunnel extension */
199 SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
200 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
201 if( xUT.is() ) {
202 return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
203 } else
204 return NULL ;
207 /* Native methods */
208 HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
209 return m_hProv ;
212 void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
213 if( m_hProv != NULL ) {
214 CryptReleaseContext( m_hProv, 0 ) ;
215 m_hProv = NULL ;
218 if( aProv != NULL ) {
219 /*- Replaced by direct adopt for WINNT support ----
220 if( !CryptContextAddRef( aProv, NULL, NULL ) )
221 throw Exception() ;
222 else
223 m_hProv = aProv ;
224 ----*/
225 m_hProv = aProv ;
229 LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
230 return m_pszContainer ;
233 void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
234 //TODO: Don't know whether or not it should be copied.
235 m_pszContainer = aKeyContainer ;
239 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) {
240 return m_hKeyStore ;
243 void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) {
244 if( m_hKeyStore != NULL ) {
245 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
246 m_hKeyStore = NULL ;
249 if( aSlot != NULL ) {
250 m_hKeyStore = CertDuplicateStore( aSlot ) ;
254 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) {
255 return m_hCertStore ;
258 void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) {
259 if( m_hCertStore != NULL ) {
260 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
261 m_hCertStore = NULL ;
264 if( aCertDb != NULL ) {
265 m_hCertStore = CertDuplicateStore( aCertDb ) ;
269 void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
270 HCRYPTKEY symkey ;
271 std::list< HCRYPTKEY >::iterator keyIt ;
273 if( aSymKey != NULL ) {
274 //First try to find the key in the list
275 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
276 if( *keyIt == aSymKey )
277 return ;
280 //If we do not find the key in the list, add a new node
281 /*- Replaced with directly adopt for WINNT 4.0 support ----
282 if( !CryptDuplicateKey( aSymKey, NULL, 0, &symkey ) )
283 throw RuntimeException() ;
284 ----*/
285 symkey = aSymKey ;
287 try {
288 m_tSymKeyList.push_back( symkey ) ;
289 } catch ( Exception& ) {
290 CryptDestroyKey( symkey ) ;
295 void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
296 HCRYPTKEY symkey ;
297 std::list< HCRYPTKEY >::iterator keyIt ;
299 if( aSymKey != NULL ) {
300 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
301 if( *keyIt == aSymKey ) {
302 symkey = *keyIt ;
303 CryptDestroyKey( symkey ) ;
304 m_tSymKeyList.erase( keyIt ) ;
305 break ;
311 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
312 HCRYPTKEY symkey ;
313 std::list< HCRYPTKEY >::iterator keyIt ;
314 unsigned int pos ;
316 symkey = NULL ;
317 for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
319 if( pos == position && keyIt != m_tSymKeyList.end() )
320 symkey = *keyIt ;
322 return symkey ;
325 void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
326 HCRYPTKEY pubkey ;
327 std::list< HCRYPTKEY >::iterator keyIt ;
329 if( aPubKey != NULL ) {
330 //First try to find the key in the list
331 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
332 if( *keyIt == aPubKey )
333 return ;
336 //If we do not find the key in the list, add a new node
337 /*- Replaced with directly adopt for WINNT 4.0 support ----
338 if( !CryptDuplicateKey( aPubKey, NULL, 0, &pubkey ) )
339 throw RuntimeException() ;
340 ----*/
341 pubkey = aPubKey ;
343 try {
344 m_tPubKeyList.push_back( pubkey ) ;
345 } catch ( Exception& ) {
346 CryptDestroyKey( pubkey ) ;
351 void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
352 HCRYPTKEY pubkey ;
353 std::list< HCRYPTKEY >::iterator keyIt ;
355 if( aPubKey != NULL ) {
356 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
357 if( *keyIt == aPubKey ) {
358 pubkey = *keyIt ;
359 CryptDestroyKey( pubkey ) ;
360 m_tPubKeyList.erase( keyIt ) ;
361 break ;
367 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
368 HCRYPTKEY pubkey ;
369 std::list< HCRYPTKEY >::iterator keyIt ;
370 unsigned int pos ;
372 pubkey = NULL ;
373 for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
375 if( pos == position && keyIt != m_tPubKeyList.end() )
376 pubkey = *keyIt ;
378 return pubkey ;
381 void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
382 HCRYPTKEY prikey ;
383 std::list< HCRYPTKEY >::iterator keyIt ;
385 if( aPriKey != NULL ) {
386 //First try to find the key in the list
387 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
388 if( *keyIt == aPriKey )
389 return ;
392 //If we do not find the key in the list, add a new node
393 /*- Replaced with directly adopt for WINNT 4.0 support ----
394 if( !CryptDuplicateKey( aPriKey, NULL, 0, &prikey ) )
395 throw RuntimeException() ;
396 ----*/
397 prikey = aPriKey ;
399 try {
400 m_tPriKeyList.push_back( prikey ) ;
401 } catch ( Exception& ) {
402 CryptDestroyKey( prikey ) ;
407 void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
408 HCRYPTKEY prikey ;
409 std::list< HCRYPTKEY >::iterator keyIt ;
411 if( aPriKey != NULL ) {
412 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
413 if( *keyIt == aPriKey ) {
414 prikey = *keyIt ;
415 CryptDestroyKey( prikey ) ;
416 m_tPriKeyList.erase( keyIt ) ;
417 break ;
423 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) {
424 HCRYPTKEY prikey ;
425 std::list< HCRYPTKEY >::iterator keyIt ;
426 unsigned int pos ;
428 prikey = NULL ;
429 for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
431 if( pos == position && keyIt != m_tPriKeyList.end() )
432 prikey = *keyIt ;
434 return prikey ;
437 //Methods from XSecurityEnvironment
438 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException )
440 sal_Int32 length ;
441 X509Certificate_MSCryptImpl* xcert ;
442 std::list< X509Certificate_MSCryptImpl* > certsList ;
443 PCCERT_CONTEXT pCertContext = NULL;
445 //firstly, we try to find private keys in given key store.
446 if( m_hKeyStore != NULL ) {
447 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
448 while (pCertContext)
450 xcert = MswcryCertContextToXCert( pCertContext ) ;
451 if( xcert != NULL )
452 certsList.push_back( xcert ) ;
453 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
457 //secondly, we try to find certificate from registered private keys.
458 if( !m_tPriKeyList.empty() ) {
459 //TODO: Don't know whether or not it is necessary ans possible.
462 //Thirdly, we try to find certificate from system default key store.
463 if( m_bEnableDefault ) {
464 HCERTSTORE hSystemKeyStore ;
465 DWORD dwKeySpec;
466 HCRYPTPROV hCryptProv;
469 hSystemKeyStore = CertOpenStore(
470 CERT_STORE_PROV_SYSTEM ,
472 NULL ,
473 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG ,
474 L"MY"
477 hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ;
478 if( hSystemKeyStore != NULL ) {
479 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
480 while (pCertContext)
482 // Add By CP for checking whether the certificate is a personal certificate or not.
483 if(!(CryptAcquireCertificatePrivateKey(pCertContext,
484 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
485 NULL,
486 &hCryptProv,
487 &dwKeySpec,
488 NULL)))
490 // Not Privatekey found. SKIP this one; By CP
491 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
492 continue;
494 // then TODO : Check the personal cert is valid or not.
496 // end CP
497 xcert = MswcryCertContextToXCert( pCertContext ) ;
498 if( xcert != NULL )
499 certsList.push_back( xcert ) ;
500 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
504 CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
507 length = certsList.size() ;
508 if( length != 0 ) {
509 int i ;
510 std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ;
511 Sequence< Reference< XCertificate > > certSeq( length ) ;
513 for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) {
514 certSeq[i] = *xcertIt ;
517 return certSeq ;
520 return Sequence< Reference< XCertificate > >() ;
524 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) {
525 unsigned int i ;
526 // sal_Int8 found = 0 ;
527 LPSTR pszName ;
528 X509Certificate_MSCryptImpl *xcert = NULL ;
529 PCCERT_CONTEXT pCertContext = NULL ;
530 HCERTSTORE hCertStore = NULL ;
531 CRYPT_INTEGER_BLOB cryptSerialNumber ;
532 CERT_INFO certInfo ;
534 // By CP , for correct encoding
535 sal_uInt16 encoding ;
536 rtl_Locale *pLocale = NULL ;
537 osl_getProcessLocale( &pLocale ) ;
538 encoding = osl_getTextEncodingFromLocale( pLocale ) ;
539 // CP end
541 //Create cert info from issue and serial
542 rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ;
543 pszName = ( char* )oissuer.getStr() ;
545 if( ! ( CertStrToName(
546 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
547 pszName ,
548 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
549 NULL ,
550 NULL ,
551 &certInfo.Issuer.cbData, NULL ) )
553 return NULL ;
556 certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData );
557 if(!certInfo.Issuer.pbData)
558 throw RuntimeException() ;
560 if( ! ( CertStrToName(
561 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
562 pszName ,
563 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
564 NULL ,
565 ( BYTE* )certInfo.Issuer.pbData ,
566 &certInfo.Issuer.cbData, NULL ) )
568 free( certInfo.Issuer.pbData ) ;
569 return NULL ;
572 //Get the SerialNumber
573 cryptSerialNumber.cbData = serialNumber.getLength() ;
574 cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData);
575 if (!cryptSerialNumber.pbData)
577 free( certInfo.Issuer.pbData ) ;
578 throw RuntimeException() ;
580 for( i = 0; i < cryptSerialNumber.cbData; i ++ )
581 cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ;
583 certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ;
584 certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ;
586 // Get the Cert from all store.
587 for( i = 0 ; i < 6 ; i ++ )
589 switch(i)
591 case 0:
592 if(m_hKeyStore == NULL) continue ;
593 hCertStore = m_hKeyStore ;
594 break;
595 case 1:
596 if(m_hCertStore == NULL) continue ;
597 hCertStore = m_hCertStore ;
598 break;
599 case 2:
600 hCertStore = CertOpenSystemStore( 0, "MY" ) ;
601 if(hCertStore == NULL || !m_bEnableDefault) continue ;
602 break;
603 case 3:
604 hCertStore = CertOpenSystemStore( 0, "Root" ) ;
605 if(hCertStore == NULL || !m_bEnableDefault) continue ;
606 break;
607 case 4:
608 hCertStore = CertOpenSystemStore( 0, "Trust" ) ;
609 if(hCertStore == NULL || !m_bEnableDefault) continue ;
610 break;
611 case 5:
612 hCertStore = CertOpenSystemStore( 0, "CA" ) ;
613 if(hCertStore == NULL || !m_bEnableDefault) continue ;
614 break;
615 default:
616 i=6;
617 continue;
620 /*******************************************************************************
621 * This code reserved for remind us there are another way to find one cert by
622 * IssuerName&serialnumber. You can use the code to replaced the function
623 * CertFindCertificateInStore IF and ONLY IF you must find one special cert in
624 * certStore but can not be found by CertFindCertificateInStore , then , you
625 * should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875.
626 * By Chandler Peng(chandler.peng@sun.com)
627 *****/
628 /*******************************************************************************
629 pCertContext = NULL ;
630 found = 0;
632 // 1. enum the certs has same string in the issuer string.
633 pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ;
634 if( pCertContext != NULL )
636 // 2. check the cert's issuer name .
637 char* issuer = NULL ;
638 DWORD cbIssuer = 0 ;
640 cbIssuer = CertNameToStr(
641 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
642 &( pCertContext->pCertInfo->Issuer ),
643 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
644 NULL, 0
647 if( cbIssuer == 0 ) continue ; // discard this cert;
649 issuer = (char *)malloc( cbIssuer ) ;
650 if( issuer == NULL ) // discard this cert;
652 free( cryptSerialNumber.pbData) ;
653 free( certInfo.Issuer.pbData ) ;
654 CertFreeCertificateContext( pCertContext ) ;
655 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
656 throw RuntimeException() ;
659 cbIssuer = CertNameToStr(
660 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
661 &( pCertContext->pCertInfo->Issuer ),
662 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
663 issuer, cbIssuer
666 if( cbIssuer <= 0 )
668 free( issuer ) ;
669 continue ;// discard this cert;
672 if(strncmp(pszName , issuer , cbIssuer) != 0)
674 free( issuer ) ;
675 continue ;// discard this cert;
677 free( issuer ) ;
679 // 3. check the serial number.
680 if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 )
682 continue ;// discard this cert;
685 // 4. confirm and break;
686 found = 1;
687 break ;
690 }while(pCertContext);
692 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
693 if( found != 0 ) break; // Found the certificate.
694 ********************************************************************************/
696 pCertContext = CertFindCertificateInStore(
697 hCertStore,
698 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
700 CERT_FIND_SUBJECT_CERT,
701 &certInfo,
702 NULL
705 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
706 if( pCertContext != NULL ) break ; // Found the certificate.
710 if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ;
711 if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ;
713 if( pCertContext != NULL ) {
714 xcert = MswcryCertContextToXCert( pCertContext ) ;
715 if( pCertContext ) CertFreeCertificateContext( pCertContext ) ;
716 } else {
717 xcert = NULL ;
720 return xcert ;
723 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
724 Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
725 return getCertificate( issuerName, serial ) ;
728 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
729 PCCERT_CHAIN_CONTEXT pChainContext ;
730 PCCERT_CONTEXT pCertContext ;
731 const X509Certificate_MSCryptImpl* xcert ;
733 CERT_ENHKEY_USAGE enhKeyUsage ;
734 CERT_USAGE_MATCH certUsage ;
735 CERT_CHAIN_PARA chainPara ;
737 enhKeyUsage.cUsageIdentifier = 0 ;
738 enhKeyUsage.rgpszUsageIdentifier = NULL ;
739 certUsage.dwType = USAGE_MATCH_TYPE_AND ;
740 certUsage.Usage = enhKeyUsage ;
741 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
742 chainPara.RequestedUsage = certUsage ;
744 Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
745 if( !xCertTunnel.is() ) {
746 throw RuntimeException() ;
749 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
750 if( xcert == NULL ) {
751 throw RuntimeException() ;
754 pCertContext = xcert->getMswcryCert() ;
756 pChainContext = NULL ;
758 BOOL bChain = FALSE;
759 if( pCertContext != NULL )
761 HCERTSTORE hAdditionalStore = NULL;
762 HCERTSTORE hCollectionStore = NULL;
763 if (m_hCertStore && m_hKeyStore)
765 //Merge m_hCertStore and m_hKeyStore into one store.
766 hCollectionStore = CertOpenStore(
767 CERT_STORE_PROV_COLLECTION ,
769 NULL ,
771 NULL
773 if (hCollectionStore != NULL)
775 CertAddStoreToCollection (
776 hCollectionStore ,
777 m_hCertStore ,
778 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
779 0) ;
780 CertAddStoreToCollection (
781 hCollectionStore ,
782 m_hCertStore ,
783 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
784 0) ;
785 hAdditionalStore = hCollectionStore;
790 //if the merge of both stores failed then we add only m_hCertStore
791 if (hAdditionalStore == NULL && m_hCertStore)
792 hAdditionalStore = m_hCertStore;
793 else if (hAdditionalStore == NULL && m_hKeyStore)
794 hAdditionalStore = m_hKeyStore;
795 else
796 hAdditionalStore = NULL;
798 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
799 bChain = CertGetCertificateChain(
800 NULL ,
801 pCertContext ,
802 NULL , //use current system time
803 hAdditionalStore,
804 &chainPara ,
805 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
806 NULL ,
807 &pChainContext);
808 if (!bChain)
809 pChainContext = NULL;
811 //Close the additional store
812 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
815 if(bChain && pChainContext != NULL && pChainContext->cChain > 0 )
817 PCCERT_CONTEXT pCertInChain ;
818 PCERT_SIMPLE_CHAIN pCertChain ;
819 X509Certificate_MSCryptImpl* pCert ;
821 pCertChain = pChainContext->rgpChain[0] ;
822 if( pCertChain->cElement ) {
823 Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ;
825 for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) {
826 if( pCertChain->rgpElement[i] )
827 pCertInChain = pCertChain->rgpElement[i]->pCertContext ;
828 else
829 pCertInChain = NULL ;
831 if( pCertInChain != NULL ) {
832 pCert = MswcryCertContextToXCert( pCertInChain ) ;
833 if( pCert != NULL )
834 xCertChain[i] = pCert ;
838 CertFreeCertificateChain( pChainContext ) ;
839 pChainContext = NULL ;
841 return xCertChain ;
844 if (pChainContext)
845 CertFreeCertificateChain(pChainContext);
847 return NULL ;
850 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
851 X509Certificate_MSCryptImpl* xcert ;
853 if( rawCertificate.getLength() > 0 ) {
854 xcert = new X509Certificate_MSCryptImpl() ;
855 if( xcert == NULL )
856 throw RuntimeException() ;
858 xcert->setRawCert( rawCertificate ) ;
859 } else {
860 xcert = NULL ;
863 return xcert ;
866 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
867 xmlChar* chCert ;
868 xmlSecSize certSize ;
870 rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
872 chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
874 certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
876 Sequence< sal_Int8 > rawCert( certSize ) ;
877 for( unsigned int i = 0 ; i < certSize ; i ++ )
878 rawCert[i] = *( chCert + i ) ;
880 xmlFree( chCert ) ;
882 return createCertificateFromRaw( rawCert ) ;
886 HCERTSTORE getCertStoreForIntermediatCerts(
887 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
889 HCERTSTORE store = NULL;
890 store = CertOpenStore(
891 CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
892 if (store == NULL)
893 return NULL;
895 for (int i = 0; i < seqCerts.getLength(); i++)
897 Sequence<sal_Int8> data = seqCerts[i]->getEncoded();
898 PCCERT_CONTEXT cert = CertCreateCertificateContext(
899 X509_ASN_ENCODING, ( const BYTE* )&data[0], data.getLength());
900 //Adding the certificate creates a copy and not just increases the ref count
901 //Therefore we free later the certificate that we now add
902 CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, NULL);
903 CertFreeCertificateContext(cert);
905 return store;
907 sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate(
908 const Reference< ::com::sun::star::security::XCertificate >& aCert,
909 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
910 throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException )
912 sal_Int32 validity = 0;
913 PCCERT_CHAIN_CONTEXT pChainContext = NULL;
914 PCCERT_CONTEXT pCertContext = NULL;
915 const X509Certificate_MSCryptImpl* xcert = NULL;
916 DWORD chainStatus ;
918 CERT_ENHKEY_USAGE enhKeyUsage ;
919 CERT_USAGE_MATCH certUsage ;
920 CERT_CHAIN_PARA chainPara ;
922 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
923 if( !xCertTunnel.is() ) {
924 throw RuntimeException() ;
927 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
928 if( xcert == NULL ) {
929 throw RuntimeException() ;
932 pCertContext = xcert->getMswcryCert() ;
934 //Prepare parameter for CertGetCertificateChain
935 enhKeyUsage.cUsageIdentifier = 0 ;
936 enhKeyUsage.rgpszUsageIdentifier = NULL ;
937 certUsage.dwType = USAGE_MATCH_TYPE_AND ;
938 certUsage.Usage = enhKeyUsage ;
939 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
940 chainPara.RequestedUsage = certUsage ;
943 HCERTSTORE hCollectionStore = NULL;
944 HCERTSTORE hIntermediateCertsStore = NULL;
945 BOOL bChain = FALSE;
946 if( pCertContext != NULL )
948 hIntermediateCertsStore =
949 getCertStoreForIntermediatCerts(seqCerts);
951 //Merge m_hCertStore and m_hKeyStore and the store of the intermediate
952 //certificates into one store.
953 hCollectionStore = CertOpenStore(
954 CERT_STORE_PROV_COLLECTION ,
956 NULL ,
958 NULL
960 if (hCollectionStore != NULL)
962 CertAddStoreToCollection (
963 hCollectionStore ,
964 m_hCertStore ,
965 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
966 0) ;
967 CertAddStoreToCollection (
968 hCollectionStore ,
969 m_hCertStore ,
970 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
971 0) ;
972 CertAddStoreToCollection (
973 hCollectionStore,
974 hIntermediateCertsStore,
975 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
980 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
981 bChain = CertGetCertificateChain(
982 NULL ,
983 pCertContext ,
984 NULL , //use current system time
985 hCollectionStore,
986 &chainPara ,
987 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
988 NULL ,
989 &pChainContext);
991 if (!bChain)
992 pChainContext = NULL;
996 if(bChain && pChainContext != NULL )
998 chainStatus = pChainContext->TrustStatus.dwErrorStatus ;
1000 // JL & TKR: Until we have a test suite to test all error types we just say that the cert is
1001 // valid or invalid with no further separation.
1002 // Error CERT_TRUST_IS_OFFLINE_REVOCATION and CERT_TRUST_REVOCATION_STATUS_UNKNOWN are treated separate
1003 // because they are ignored ( Bad! ) in the currently situation
1005 if( chainStatus == CERT_TRUST_NO_ERROR )
1007 validity = ::com::sun::star::security::CertificateValidity::VALID ;
1010 if ( ( chainStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ) == CERT_TRUST_IS_OFFLINE_REVOCATION ) {
1011 validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ;
1014 if ( ( chainStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) == CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) {
1015 validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ;
1018 if (chainStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE
1019 || chainStatus & CERT_TRUST_IS_CYCLIC
1020 || chainStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS
1021 || chainStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS
1022 || chainStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS
1023 || chainStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
1024 || chainStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
1025 || chainStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
1026 || chainStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
1027 || chainStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY
1028 || chainStatus & CERT_TRUST_CTL_IS_NOT_TIME_VALID
1029 || chainStatus & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID
1030 || chainStatus & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE
1031 || chainStatus & CERT_TRUST_IS_NOT_TIME_VALID
1032 || chainStatus & CERT_TRUST_IS_NOT_TIME_NESTED
1033 || chainStatus & CERT_TRUST_IS_REVOKED
1034 || chainStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID
1035 || chainStatus & CERT_TRUST_IS_UNTRUSTED_ROOT
1036 || chainStatus & CERT_TRUST_INVALID_EXTENSION
1037 || chainStatus & CERT_TRUST_IS_PARTIAL_CHAIN )
1039 validity = ::com::sun::star::security::CertificateValidity::INVALID;
1043 if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_VALID ) == CERT_TRUST_IS_NOT_TIME_VALID ) {
1044 validity |= ::com::sun::star::security::CertificateValidity::TIME_INVALID ;
1047 if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_NESTED ) == CERT_TRUST_IS_NOT_TIME_NESTED ) {
1048 validity |= ::com::sun::star::security::CertificateValidity::NOT_TIME_NESTED;
1051 if( ( chainStatus & CERT_TRUST_IS_REVOKED ) == CERT_TRUST_IS_REVOKED ) {
1052 validity |= ::com::sun::star::security::CertificateValidity::REVOKED ;
1055 //JL My interpretation is that CERT_TRUST_IS_OFFLINE_REVOCATION does not mean that the certificate was revoked.
1056 //Instead the CRL cannot be retrieved from the net, or an available CRL is stale (too old).
1057 //This error may also occurs if the certificate does not contain the CDP (Certificate Distribution Point)extension
1058 if( ( chainStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ) == CERT_TRUST_IS_OFFLINE_REVOCATION ) {
1059 validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ;
1062 if( ( chainStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID ) == CERT_TRUST_IS_NOT_SIGNATURE_VALID ) {
1063 validity |= ::com::sun::star::security::CertificateValidity::SIGNATURE_INVALID ;
1066 if( ( chainStatus & CERT_TRUST_IS_UNTRUSTED_ROOT ) == CERT_TRUST_IS_UNTRUSTED_ROOT ) {
1067 validity |= ::com::sun::star::security::CertificateValidity::ROOT_UNTRUSTED ;
1070 if( ( chainStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) == CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) {
1071 validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ;
1074 if( ( chainStatus & CERT_TRUST_INVALID_EXTENSION ) == CERT_TRUST_INVALID_EXTENSION ) {
1075 validity |= ::com::sun::star::security::CertificateValidity::EXTENSION_INVALID ;
1078 if( ( chainStatus & CERT_TRUST_IS_PARTIAL_CHAIN ) == CERT_TRUST_IS_PARTIAL_CHAIN ) {
1079 validity |= ::com::sun::star::security::CertificateValidity::CHAIN_INCOMPLETE ;
1081 //todo
1082 if (chainStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE
1083 || chainStatus & CERT_TRUST_IS_CYCLIC
1084 || chainStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS
1085 || chainStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS
1086 || chainStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS
1087 || chainStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
1088 || chainStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
1089 || chainStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
1090 || chainStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
1091 || chainStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY
1092 || chainStatus & CERT_TRUST_CTL_IS_NOT_TIME_VALID
1093 || chainStatus & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID
1094 || chainStatus & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE)
1096 validity = ::com::sun::star::security::CertificateValidity::INVALID;
1099 } else {
1100 validity = ::com::sun::star::security::CertificateValidity::INVALID ;
1103 if (pChainContext)
1104 CertFreeCertificateChain(pChainContext);
1106 //Close the additional store, do not destroy the contained certs
1107 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
1108 //Close the temporary store containing the intermediate certificates and make
1109 //sure all certificates are deleted.
1110 CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG);
1112 return validity ;
1115 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 ) {
1116 sal_Int32 characters ;
1117 PCCERT_CONTEXT pCertContext ;
1118 const X509Certificate_MSCryptImpl* xcert ;
1120 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
1121 if( !xCertTunnel.is() ) {
1122 throw RuntimeException() ;
1125 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
1126 if( xcert == NULL ) {
1127 throw RuntimeException() ;
1130 pCertContext = xcert->getMswcryCert() ;
1132 characters = 0x00000000 ;
1134 //Firstly, make sentence whether or not the cert is self-signed.
1135 if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) {
1136 characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1137 } else {
1138 characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1141 //Secondly, make sentence whether or not the cert has a private key.
1143 BOOL fCallerFreeProv ;
1144 DWORD dwKeySpec ;
1145 HCRYPTPROV hProv ;
1146 if( CryptAcquireCertificatePrivateKey( pCertContext ,
1148 NULL ,
1149 &( hProv ) ,
1150 &( dwKeySpec ) ,
1151 &( fCallerFreeProv ) )
1153 characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1155 if( hProv != NULL && fCallerFreeProv )
1156 CryptReleaseContext( hProv, 0 ) ;
1157 } else {
1158 characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1161 return characters ;
1164 void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) {
1165 m_bEnableDefault = enable ;
1168 sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) {
1169 return m_bEnableDefault ;
1172 X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert )
1174 X509Certificate_MSCryptImpl* xcert ;
1176 if( cert != NULL ) {
1177 xcert = new X509Certificate_MSCryptImpl() ;
1178 if( xcert != NULL ) {
1179 xcert->setMswcryCert( cert ) ;
1181 } else {
1182 xcert = NULL ;
1185 return xcert ;
1188 ::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
1190 return rtl::OUString::createFromAscii("Microsoft Crypto API");
1193 /* Native methods */
1194 xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) {
1196 unsigned int i ;
1197 HCRYPTKEY symKey ;
1198 HCRYPTKEY pubKey ;
1199 HCRYPTKEY priKey ;
1200 xmlSecKeysMngrPtr pKeysMngr = NULL ;
1203 * The following lines is based on the of xmlsec-mscrypto crypto engine
1205 pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ;
1206 if( pKeysMngr == NULL )
1207 throw RuntimeException() ;
1210 * Adopt symmetric key into keys manager
1212 for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) {
1213 if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
1214 throw RuntimeException() ;
1219 * Adopt asymmetric public key into keys manager
1221 for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) {
1222 if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
1223 throw RuntimeException() ;
1228 * Adopt asymmetric private key into keys manager
1230 for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) {
1231 if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
1232 throw RuntimeException() ;
1237 * Adopt system default certificate store.
1239 if( defaultEnabled() ) {
1240 HCERTSTORE hSystemStore ;
1242 //Add system key store into the keys manager.
1243 hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
1244 if( hSystemStore != NULL ) {
1245 if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, hSystemStore ) < 0 ) {
1246 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1247 throw RuntimeException() ;
1251 //Add system root store into the keys manager.
1252 hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
1253 if( hSystemStore != NULL ) {
1254 if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1255 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1256 throw RuntimeException() ;
1260 //Add system trusted store into the keys manager.
1261 hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
1262 if( hSystemStore != NULL ) {
1263 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1264 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1265 throw RuntimeException() ;
1269 //Add system CA store into the keys manager.
1270 hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
1271 if( hSystemStore != NULL ) {
1272 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
1273 CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1274 throw RuntimeException() ;
1279 return pKeysMngr ;
1281 void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
1282 if( pKeysMngr != NULL ) {
1283 xmlSecKeysMngrDestroy( pKeysMngr ) ;