1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmlsecurity.hxx" 30 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" 42 43 #ifndef _X509CERTIFICATE_NSSIMPL_HXX_ 44 #include "x509certificate_mscryptimpl.hxx" 45 #endif 46 #include <rtl/uuid.h> 47 48 #include <xmlsec/xmlsec.h> 49 #include <xmlsec/keysmngr.h> 50 #include <xmlsec/crypto.h> 51 #include <xmlsec/base64.h> 52 53 #include <xmlsecurity/biginteger.hxx> 54 55 #include "xmlsec/keysmngr.h" 56 #include "xmlsec/mscrypto/akmngr.h" 57 58 //CP : added by CP 59 #include <rtl/locale.h> 60 #include <osl/nlsupport.h> 61 #include <osl/process.h> 62 63 //CP : end 64 #include <rtl/memory.h> 65 66 #include "../diagnose.hxx" 67 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 ; 74 75 using ::com::sun::star::xml::crypto::XSecurityEnvironment ; 76 using ::com::sun::star::security::XCertificate ; 77 namespace css = ::com::sun::star; 78 79 extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ; 80 81 struct CertErrorToString{ 82 DWORD error; 83 char * name; 84 }; 85 86 CertErrorToString arErrStrings[] = 87 { 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"} 114 }; 115 116 void traceTrustStatus(DWORD err) 117 { 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++) 123 { 124 if (arErrStrings[i].error & err) 125 xmlsec_trace("%s", arErrStrings[i].name); 126 } 127 } 128 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 ) { 130 131 } 132 133 SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() { 134 135 if( m_hProv != NULL ) { 136 CryptReleaseContext( m_hProv, 0 ) ; 137 m_hProv = NULL ; 138 } 139 140 if( m_pszContainer != NULL ) { 141 //TODO: Don't know whether or not it should be released now. 142 m_pszContainer = NULL ; 143 } 144 145 if( m_hCertStore != NULL ) { 146 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 147 m_hCertStore = NULL ; 148 } 149 150 if( m_hKeyStore != NULL ) { 151 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 152 m_hKeyStore = NULL ; 153 } 154 155 if( !m_tSymKeyList.empty() ) { 156 std::list< HCRYPTKEY >::iterator symKeyIt ; 157 158 for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ ) 159 CryptDestroyKey( *symKeyIt ) ; 160 } 161 162 if( !m_tPubKeyList.empty() ) { 163 std::list< HCRYPTKEY >::iterator pubKeyIt ; 164 165 for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ ) 166 CryptDestroyKey( *pubKeyIt ) ; 167 } 168 169 if( !m_tPriKeyList.empty() ) { 170 std::list< HCRYPTKEY >::iterator priKeyIt ; 171 172 for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ ) 173 CryptDestroyKey( *priKeyIt ) ; 174 } 175 176 } 177 178 /* XInitialization */ 179 void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { 180 //TODO 181 } ; 182 183 /* XServiceInfo */ 184 OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { 185 return impl_getImplementationName() ; 186 } 187 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 ; 195 } 196 return sal_False ; 197 } 198 199 /* XServiceInfo */ 200 Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { 201 return impl_getSupportedServiceNames() ; 202 } 203 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 ; 210 } 211 212 OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { 213 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ; 214 } 215 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 ) ) ; 219 } 220 221 Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 222 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 223 } 224 225 /* XUnoTunnel */ 226 sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) 227 throw( RuntimeException ) 228 { 229 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { 230 return ( sal_Int64 )this ; 231 } 232 return 0 ; 233 } 234 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 ; 244 } 245 } 246 return *pSeq ; 247 } 248 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 ; 256 } 257 258 /* Native methods */ 259 HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 260 return m_hProv ; 261 } 262 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 ; 267 } 268 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 ; 277 } 278 } 279 280 LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 281 return m_pszContainer ; 282 } 283 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 ; 287 } 288 289 290 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) { 291 return m_hKeyStore ; 292 } 293 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 ; 298 } 299 300 if( aSlot != NULL ) { 301 m_hKeyStore = CertDuplicateStore( aSlot ) ; 302 } 303 } 304 305 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) { 306 return m_hCertStore ; 307 } 308 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 ; 313 } 314 315 if( aCertDb != NULL ) { 316 m_hCertStore = CertDuplicateStore( aCertDb ) ; 317 } 318 } 319 320 void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { 321 HCRYPTKEY symkey ; 322 std::list< HCRYPTKEY >::iterator keyIt ; 323 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 ; 329 } 330 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 ; 337 338 try { 339 m_tSymKeyList.push_back( symkey ) ; 340 } catch ( Exception& ) { 341 CryptDestroyKey( symkey ) ; 342 } 343 } 344 } 345 346 void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { 347 HCRYPTKEY symkey ; 348 std::list< HCRYPTKEY >::iterator keyIt ; 349 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 ; 357 } 358 } 359 } 360 } 361 362 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) { 363 HCRYPTKEY symkey ; 364 std::list< HCRYPTKEY >::iterator keyIt ; 365 unsigned int pos ; 366 367 symkey = NULL ; 368 for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ; 369 370 if( pos == position && keyIt != m_tSymKeyList.end() ) 371 symkey = *keyIt ; 372 373 return symkey ; 374 } 375 376 void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { 377 HCRYPTKEY pubkey ; 378 std::list< HCRYPTKEY >::iterator keyIt ; 379 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 ; 385 } 386 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 ; 393 394 try { 395 m_tPubKeyList.push_back( pubkey ) ; 396 } catch ( Exception& ) { 397 CryptDestroyKey( pubkey ) ; 398 } 399 } 400 } 401 402 void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { 403 HCRYPTKEY pubkey ; 404 std::list< HCRYPTKEY >::iterator keyIt ; 405 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 ; 413 } 414 } 415 } 416 } 417 418 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) { 419 HCRYPTKEY pubkey ; 420 std::list< HCRYPTKEY >::iterator keyIt ; 421 unsigned int pos ; 422 423 pubkey = NULL ; 424 for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ; 425 426 if( pos == position && keyIt != m_tPubKeyList.end() ) 427 pubkey = *keyIt ; 428 429 return pubkey ; 430 } 431 432 void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { 433 HCRYPTKEY prikey ; 434 std::list< HCRYPTKEY >::iterator keyIt ; 435 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 ; 441 } 442 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 ; 449 450 try { 451 m_tPriKeyList.push_back( prikey ) ; 452 } catch ( Exception& ) { 453 CryptDestroyKey( prikey ) ; 454 } 455 } 456 } 457 458 void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { 459 HCRYPTKEY prikey ; 460 std::list< HCRYPTKEY >::iterator keyIt ; 461 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 ; 469 } 470 } 471 } 472 } 473 474 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) { 475 HCRYPTKEY prikey ; 476 std::list< HCRYPTKEY >::iterator keyIt ; 477 unsigned int pos ; 478 479 prikey = NULL ; 480 for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ; 481 482 if( pos == position && keyIt != m_tPriKeyList.end() ) 483 prikey = *keyIt ; 484 485 return prikey ; 486 } 487 488 //Methods from XSecurityEnvironment 489 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException ) 490 { 491 sal_Int32 length ; 492 X509Certificate_MSCryptImpl* xcert ; 493 std::list< X509Certificate_MSCryptImpl* > certsList ; 494 PCCERT_CONTEXT pCertContext = NULL; 495 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) 500 { 501 xcert = MswcryCertContextToXCert( pCertContext ) ; 502 if( xcert != NULL ) 503 certsList.push_back( xcert ) ; 504 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ); 505 } 506 } 507 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. 511 } 512 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; 518 519 /* 520 hSystemKeyStore = CertOpenStore( 521 CERT_STORE_PROV_SYSTEM , 522 0 , 523 NULL , 524 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG , 525 L"MY" 526 ) ; 527 */ 528 hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ; 529 if( hSystemKeyStore != NULL ) { 530 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 531 while (pCertContext) 532 { 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))) 540 { 541 // Not Privatekey found. SKIP this one; By CP 542 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 543 continue; 544 } 545 // then TODO : Check the personal cert is valid or not. 546 547 // end CP 548 xcert = MswcryCertContextToXCert( pCertContext ) ; 549 if( xcert != NULL ) 550 certsList.push_back( xcert ) ; 551 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 552 } 553 } 554 555 CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 556 } 557 558 length = certsList.size() ; 559 if( length != 0 ) { 560 int i ; 561 std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ; 562 Sequence< Reference< XCertificate > > certSeq( length ) ; 563 564 for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) { 565 certSeq[i] = *xcertIt ; 566 } 567 568 return certSeq ; 569 } 570 571 return Sequence< Reference< XCertificate > >() ; 572 } 573 574 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 ; 584 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 591 592 //Create cert info from issue and serial 593 rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ; 594 pszName = ( char* )oissuer.getStr() ; 595 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 ) ) 603 ) { 604 return NULL ; 605 } 606 607 certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData ); 608 if(!certInfo.Issuer.pbData) 609 throw RuntimeException() ; 610 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 ) ) 618 ) { 619 free( certInfo.Issuer.pbData ) ; 620 return NULL ; 621 } 622 623 //Get the SerialNumber 624 cryptSerialNumber.cbData = serialNumber.getLength() ; 625 cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData); 626 if (!cryptSerialNumber.pbData) 627 { 628 free( certInfo.Issuer.pbData ) ; 629 throw RuntimeException() ; 630 } 631 for( i = 0; i < cryptSerialNumber.cbData; i ++ ) 632 cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ; 633 634 certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ; 635 certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ; 636 637 // Get the Cert from all store. 638 for( i = 0 ; i < 6 ; i ++ ) 639 { 640 switch(i) 641 { 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; 669 } 670 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; 682 do{ 683 // 1. enum the certs has same string in the issuer string. 684 pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ; 685 if( pCertContext != NULL ) 686 { 687 // 2. check the cert's issuer name . 688 char* issuer = NULL ; 689 DWORD cbIssuer = 0 ; 690 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 696 ) ; 697 698 if( cbIssuer == 0 ) continue ; // discard this cert; 699 700 issuer = (char *)malloc( cbIssuer ) ; 701 if( issuer == NULL ) // discard this cert; 702 { 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() ; 708 } 709 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 715 ) ; 716 717 if( cbIssuer <= 0 ) 718 { 719 free( issuer ) ; 720 continue ;// discard this cert; 721 } 722 723 if(strncmp(pszName , issuer , cbIssuer) != 0) 724 { 725 free( issuer ) ; 726 continue ;// discard this cert; 727 } 728 free( issuer ) ; 729 730 // 3. check the serial number. 731 if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 ) 732 { 733 continue ;// discard this cert; 734 } 735 736 // 4. confirm and break; 737 found = 1; 738 break ; 739 } 740 741 }while(pCertContext); 742 743 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 744 if( found != 0 ) break; // Found the certificate. 745 ********************************************************************************/ 746 747 pCertContext = CertFindCertificateInStore( 748 hCertStore, 749 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 750 0, 751 CERT_FIND_SUBJECT_CERT, 752 &certInfo, 753 NULL 754 ) ; 755 756 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 757 if( pCertContext != NULL ) break ; // Found the certificate. 758 759 } 760 761 if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ; 762 if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ; 763 764 if( pCertContext != NULL ) { 765 xcert = MswcryCertContextToXCert( pCertContext ) ; 766 if( pCertContext ) CertFreeCertificateContext( pCertContext ) ; 767 } else { 768 xcert = NULL ; 769 } 770 771 return xcert ; 772 } 773 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 ) ; 777 } 778 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 ; 783 784 CERT_ENHKEY_USAGE enhKeyUsage ; 785 CERT_USAGE_MATCH certUsage ; 786 CERT_CHAIN_PARA chainPara ; 787 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 ; 794 795 Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ; 796 if( !xCertTunnel.is() ) { 797 throw RuntimeException() ; 798 } 799 800 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 801 if( xcert == NULL ) { 802 throw RuntimeException() ; 803 } 804 805 pCertContext = xcert->getMswcryCert() ; 806 807 pChainContext = NULL ; 808 809 BOOL bChain = FALSE; 810 if( pCertContext != NULL ) 811 { 812 HCERTSTORE hAdditionalStore = NULL; 813 HCERTSTORE hCollectionStore = NULL; 814 if (m_hCertStore && m_hKeyStore) 815 { 816 //Merge m_hCertStore and m_hKeyStore into one store. 817 hCollectionStore = CertOpenStore( 818 CERT_STORE_PROV_COLLECTION , 819 0 , 820 NULL , 821 0 , 822 NULL 823 ) ; 824 if (hCollectionStore != NULL) 825 { 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; 837 } 838 839 } 840 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; 848 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; 861 862 //Close the additional store 863 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); 864 } 865 866 if(bChain && pChainContext != NULL && pChainContext->cChain > 0 ) 867 { 868 PCCERT_CONTEXT pCertInChain ; 869 PCERT_SIMPLE_CHAIN pCertChain ; 870 X509Certificate_MSCryptImpl* pCert ; 871 872 pCertChain = pChainContext->rgpChain[0] ; 873 if( pCertChain->cElement ) { 874 Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ; 875 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 ; 881 882 if( pCertInChain != NULL ) { 883 pCert = MswcryCertContextToXCert( pCertInChain ) ; 884 if( pCert != NULL ) 885 xCertChain[i] = pCert ; 886 } 887 } 888 889 CertFreeCertificateChain( pChainContext ) ; 890 pChainContext = NULL ; 891 892 return xCertChain ; 893 } 894 } 895 if (pChainContext) 896 CertFreeCertificateChain(pChainContext); 897 898 return Sequence< Reference < XCertificate > >(); 899 } 900 901 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) { 902 X509Certificate_MSCryptImpl* xcert ; 903 904 if( rawCertificate.getLength() > 0 ) { 905 xcert = new X509Certificate_MSCryptImpl() ; 906 if( xcert == NULL ) 907 throw RuntimeException() ; 908 909 xcert->setRawCert( rawCertificate ) ; 910 } else { 911 xcert = NULL ; 912 } 913 914 return xcert ; 915 } 916 917 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) { 918 xmlChar* chCert ; 919 xmlSecSize certSize ; 920 921 rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ; 922 923 chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ; 924 925 certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ; 926 927 Sequence< sal_Int8 > rawCert( certSize ) ; 928 for( unsigned int i = 0 ; i < certSize ; i ++ ) 929 rawCert[i] = *( chCert + i ) ; 930 931 xmlFree( chCert ) ; 932 933 return createCertificateFromRaw( rawCert ) ; 934 } 935 936 937 HCERTSTORE getCertStoreForIntermediatCerts( 938 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts) 939 { 940 HCERTSTORE store = NULL; 941 store = CertOpenStore( 942 CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); 943 if (store == NULL) 944 return NULL; 945 946 for (int i = 0; i < seqCerts.getLength(); i++) 947 { 948 xmlsec_trace("Added temporary certificate: \n%s", 949 OUStringToOString(seqCerts[i]->getSubjectName(), 950 osl_getThreadTextEncoding()).getStr()); 951 952 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); 960 } 961 return store; 962 } 963 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 ) 972 { 973 sal_Int32 validity = 0; 974 PCCERT_CHAIN_CONTEXT pChainContext = NULL; 975 PCCERT_CONTEXT pCertContext = NULL; 976 const X509Certificate_MSCryptImpl* xcert = NULL; 977 978 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; 979 if( !xCertTunnel.is() ) { 980 throw RuntimeException() ; 981 } 982 983 xmlsec_trace("Start verification of certificate: \n %s", 984 OUStringToOString( 985 aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr()); 986 987 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 988 if( xcert == NULL ) { 989 throw RuntimeException() ; 990 } 991 992 pCertContext = xcert->getMswcryCert() ; 993 994 CERT_ENHKEY_USAGE enhKeyUsage ; 995 CERT_USAGE_MATCH certUsage ; 996 CERT_CHAIN_PARA chainPara ; 997 rtl_zeroMemory(&chainPara, sizeof(CERT_CHAIN_PARA)); 998 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 ; 1006 1007 1008 HCERTSTORE hCollectionStore = NULL; 1009 HCERTSTORE hIntermediateCertsStore = NULL; 1010 BOOL bChain = FALSE; 1011 if( pCertContext != NULL ) 1012 { 1013 hIntermediateCertsStore = 1014 getCertStoreForIntermediatCerts(seqCerts); 1015 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 , 1020 0 , 1021 NULL , 1022 0 , 1023 NULL 1024 ) ; 1025 if (hCollectionStore != NULL) 1026 { 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, 1041 0); 1042 1043 } 1044 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); 1058 1059 if (bChain && pChainContext->cChain > 0) 1060 { 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); 1067 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)) 1074 1075 { 1076 //No errors except maybe those caused by missing revocation information 1077 //Check if there are errors 1078 if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags) 1079 { 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 , 1092 0, 1093 NULL , 1094 &pChainContext); 1095 if (bChain 1096 && pChainContext->cChain > 0 1097 && pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) 1098 { 1099 xmlsec_trace("Certificate is valid.\n"); 1100 validity = ::com::sun::star::security::CertificateValidity::VALID; 1101 } 1102 else 1103 { 1104 xmlsec_trace("Certificate is invalid.\n"); 1105 } 1106 } 1107 else 1108 { 1109 //valid and revocation information available 1110 xmlsec_trace("Certificate is valid.\n"); 1111 validity = ::com::sun::star::security::CertificateValidity::VALID; 1112 } 1113 } 1114 else 1115 { 1116 //invalid 1117 xmlsec_trace("Certificate is invalid.\n"); 1118 validity = ::com::sun::star::security::CertificateValidity::INVALID ; 1119 } 1120 } 1121 else 1122 { 1123 xmlsec_trace("CertGetCertificateChaine failed.\n"); 1124 } 1125 } 1126 1127 if (pChainContext) 1128 { 1129 CertFreeCertificateChain(pChainContext); 1130 pChainContext = NULL; 1131 } 1132 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); 1138 1139 return validity ; 1140 } 1141 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 ; 1146 1147 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; 1148 if( !xCertTunnel.is() ) { 1149 throw RuntimeException() ; 1150 } 1151 1152 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 1153 if( xcert == NULL ) { 1154 throw RuntimeException() ; 1155 } 1156 1157 pCertContext = xcert->getMswcryCert() ; 1158 1159 characters = 0x00000000 ; 1160 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 ; 1166 } 1167 1168 //Secondly, make sentence whether or not the cert has a private key. 1169 { 1170 BOOL fCallerFreeProv ; 1171 DWORD dwKeySpec ; 1172 HCRYPTPROV hProv ; 1173 if( CryptAcquireCertificatePrivateKey( pCertContext , 1174 0 , 1175 NULL , 1176 &( hProv ) , 1177 &( dwKeySpec ) , 1178 &( fCallerFreeProv ) ) 1179 ) { 1180 characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; 1181 1182 if( hProv != NULL && fCallerFreeProv ) 1183 CryptReleaseContext( hProv, 0 ) ; 1184 } else { 1185 characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; 1186 } 1187 } 1188 return characters ; 1189 } 1190 1191 void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) { 1192 m_bEnableDefault = enable ; 1193 } 1194 1195 sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) { 1196 return m_bEnableDefault ; 1197 } 1198 1199 X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) 1200 { 1201 X509Certificate_MSCryptImpl* xcert ; 1202 1203 if( cert != NULL ) { 1204 xcert = new X509Certificate_MSCryptImpl() ; 1205 if( xcert != NULL ) { 1206 xcert->setMswcryCert( cert ) ; 1207 } 1208 } else { 1209 xcert = NULL ; 1210 } 1211 1212 return xcert ; 1213 } 1214 1215 ::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException ) 1216 { 1217 return rtl::OUString::createFromAscii("Microsoft Crypto API"); 1218 } 1219 1220 /* Native methods */ 1221 xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) { 1222 1223 unsigned int i ; 1224 HCRYPTKEY symKey ; 1225 HCRYPTKEY pubKey ; 1226 HCRYPTKEY priKey ; 1227 xmlSecKeysMngrPtr pKeysMngr = NULL ; 1228 1229 /*- 1230 * The following lines is based on the of xmlsec-mscrypto crypto engine 1231 */ 1232 pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ; 1233 if( pKeysMngr == NULL ) 1234 throw RuntimeException() ; 1235 1236 /*- 1237 * Adopt symmetric key into keys manager 1238 */ 1239 for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) { 1240 if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) { 1241 throw RuntimeException() ; 1242 } 1243 } 1244 1245 /*- 1246 * Adopt asymmetric public key into keys manager 1247 */ 1248 for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) { 1249 if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) { 1250 throw RuntimeException() ; 1251 } 1252 } 1253 1254 /*- 1255 * Adopt asymmetric private key into keys manager 1256 */ 1257 for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) { 1258 if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) { 1259 throw RuntimeException() ; 1260 } 1261 } 1262 1263 /*- 1264 * Adopt system default certificate store. 1265 */ 1266 if( defaultEnabled() ) { 1267 HCERTSTORE hSystemStore ; 1268 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() ; 1275 } 1276 } 1277 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() ; 1284 } 1285 } 1286 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() ; 1293 } 1294 } 1295 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() ; 1302 } 1303 } 1304 } 1305 1306 return pKeysMngr ; 1307 } 1308 void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) { 1309 if( pKeysMngr != NULL ) { 1310 xmlSecKeysMngrDestroy( pKeysMngr ) ; 1311 } 1312 } 1313