1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmlsecurity.hxx" 26 27 #ifdef _MSC_VER 28 #pragma warning(push,1) 29 #endif 30 #include "Windows.h" 31 #include "WinCrypt.h" 32 #ifdef _MSC_VER 33 #pragma warning(pop) 34 #endif 35 #include <sal/config.h> 36 #include <osl/thread.h> 37 #include "securityenvironment_mscryptimpl.hxx" 38 39 #ifndef _X509CERTIFICATE_NSSIMPL_HXX_ 40 #include "x509certificate_mscryptimpl.hxx" 41 #endif 42 #include <rtl/uuid.h> 43 44 #include <xmlsec/xmlsec.h> 45 #include <xmlsec/keysmngr.h> 46 #include <xmlsec/crypto.h> 47 #include <xmlsec/base64.h> 48 49 #include <xmlsecurity/biginteger.hxx> 50 51 #include "xmlsec/keysmngr.h" 52 #include "xmlsec/mscrypto/akmngr.h" 53 54 //CP : added by CP 55 #include <rtl/locale.h> 56 #include <osl/nlsupport.h> 57 #include <osl/process.h> 58 59 //CP : end 60 #include <rtl/memory.h> 61 62 #include "../diagnose.hxx" 63 64 using namespace xmlsecurity; 65 using namespace ::com::sun::star::uno ; 66 using namespace ::com::sun::star::lang ; 67 using ::com::sun::star::lang::XMultiServiceFactory ; 68 using ::com::sun::star::lang::XSingleServiceFactory ; 69 using ::rtl::OUString ; 70 71 using ::com::sun::star::xml::crypto::XSecurityEnvironment ; 72 using ::com::sun::star::security::XCertificate ; 73 namespace css = ::com::sun::star; 74 75 extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ; 76 77 struct CertErrorToString{ 78 DWORD error; 79 char * name; 80 }; 81 82 CertErrorToString arErrStrings[] = 83 { 84 { 0x00000000, "CERT_TRUST_NO_ERROR"}, 85 { 0x00000001, "CERT_TRUST_IS_NOT_TIME_VALID"}, 86 { 0x00000002, "CERT_TRUST_IS_NOT_TIME_NESTED"}, 87 { 0x00000004, "CERT_TRUST_IS_REVOKED" }, 88 { 0x00000008, "CERT_TRUST_IS_NOT_SIGNATURE_VALID" }, 89 { 0x00000010, "CERT_TRUST_IS_NOT_SIGNATURE_VALID"}, 90 { 0x00000020, "CERT_TRUST_IS_UNTRUSTED_ROOT"}, 91 { 0x00000040, "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"}, 92 { 0x00000080, "CERT_TRUST_IS_CYCLIC"}, 93 { 0x00000100, "CERT_TRUST_INVALID_EXTENSION"}, 94 { 0x00000200, "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"}, 95 { 0x00000400, "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"}, 96 { 0x00000800, "CERT_TRUST_INVALID_NAME_CONSTRAINTS"}, 97 { 0x00001000, "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"}, 98 { 0x00002000, "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"}, 99 { 0x00004000, "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"}, 100 { 0x00008000, "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"}, 101 { 0x01000000, "CERT_TRUST_IS_OFFLINE_REVOCATION"}, 102 { 0x02000000, "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"}, 103 { 0x04000000, "CERT_TRUST_IS_EXPLICIT_DISTRUST"}, 104 { 0x08000000, "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"}, 105 //Chain errors 106 { 0x00010000, "CERT_TRUST_IS_PARTIAL_CHAIN"}, 107 { 0x00020000, "CERT_TRUST_CTL_IS_NOT_TIME_VALID"}, 108 { 0x00040000, "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"}, 109 { 0x00080000, "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"} 110 }; 111 112 void traceTrustStatus(DWORD err) 113 { 114 int numErrors = sizeof(arErrStrings) / sizeof(CertErrorToString); 115 xmlsec_trace("The certificate error status is: "); 116 if (err == 0) 117 xmlsec_trace("%s", arErrStrings[0].name); 118 for (int i = 1; i < numErrors; i++) 119 { 120 if (arErrStrings[i].error & err) 121 xmlsec_trace("%s", arErrStrings[i].name); 122 } 123 } 124 125 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 ), m_hMySystemStore(NULL), m_hRootSystemStore(NULL), m_hTrustSystemStore(NULL), m_hCaSystemStore(NULL){ 126 127 } 128 129 SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() { 130 131 if( m_hProv != NULL ) { 132 CryptReleaseContext( m_hProv, 0 ) ; 133 m_hProv = NULL ; 134 } 135 136 if( m_pszContainer != NULL ) { 137 //TODO: Don't know whether or not it should be released now. 138 m_pszContainer = NULL ; 139 } 140 141 if( m_hCertStore != NULL ) { 142 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 143 m_hCertStore = NULL ; 144 } 145 146 if( m_hKeyStore != NULL ) { 147 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 148 m_hKeyStore = NULL ; 149 } 150 151 //i120675, close the store handles 152 if( m_hMySystemStore != NULL ) { 153 CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 154 m_hMySystemStore = NULL ; 155 } 156 157 if( m_hRootSystemStore != NULL ) { 158 CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 159 m_hRootSystemStore = NULL ; 160 } 161 162 if( m_hTrustSystemStore != NULL ) { 163 CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 164 m_hTrustSystemStore = NULL ; 165 } 166 167 if( m_hCaSystemStore != NULL ) { 168 CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 169 m_hCaSystemStore = NULL ; 170 } 171 172 if( !m_tSymKeyList.empty() ) { 173 std::list< HCRYPTKEY >::iterator symKeyIt ; 174 175 for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ ) 176 CryptDestroyKey( *symKeyIt ) ; 177 } 178 179 if( !m_tPubKeyList.empty() ) { 180 std::list< HCRYPTKEY >::iterator pubKeyIt ; 181 182 for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ ) 183 CryptDestroyKey( *pubKeyIt ) ; 184 } 185 186 if( !m_tPriKeyList.empty() ) { 187 std::list< HCRYPTKEY >::iterator priKeyIt ; 188 189 for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ ) 190 CryptDestroyKey( *priKeyIt ) ; 191 } 192 193 } 194 195 /* XInitialization */ 196 void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { 197 //TODO 198 } ; 199 200 /* XServiceInfo */ 201 OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { 202 return impl_getImplementationName() ; 203 } 204 205 /* XServiceInfo */ 206 sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { 207 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; 208 const OUString* pArray = seqServiceNames.getConstArray() ; 209 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { 210 if( *( pArray + i ) == serviceName ) 211 return sal_True ; 212 } 213 return sal_False ; 214 } 215 216 /* XServiceInfo */ 217 Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { 218 return impl_getSupportedServiceNames() ; 219 } 220 221 //Helper for XServiceInfo 222 Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() { 223 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 224 Sequence< OUString > seqServiceNames( 1 ) ; 225 seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ; 226 return seqServiceNames ; 227 } 228 229 OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { 230 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ; 231 } 232 233 //Helper for registry 234 Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { 235 return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ; 236 } 237 238 Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { 239 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; 240 } 241 242 /* XUnoTunnel */ 243 sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) 244 throw( RuntimeException ) 245 { 246 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { 247 return ( sal_Int64 )this ; 248 } 249 return 0 ; 250 } 251 252 /* XUnoTunnel extension */ 253 const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() { 254 static Sequence< sal_Int8 >* pSeq = 0 ; 255 if( !pSeq ) { 256 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 257 if( !pSeq ) { 258 static Sequence< sal_Int8> aSeq( 16 ) ; 259 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; 260 pSeq = &aSeq ; 261 } 262 } 263 return *pSeq ; 264 } 265 266 /* XUnoTunnel extension */ 267 SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) { 268 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; 269 if( xUT.is() ) { 270 return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ; 271 } else 272 return NULL ; 273 } 274 275 /* Native methods */ 276 HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 277 return m_hProv ; 278 } 279 280 void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 281 if( m_hProv != NULL ) { 282 CryptReleaseContext( m_hProv, 0 ) ; 283 m_hProv = NULL ; 284 } 285 286 if( aProv != NULL ) { 287 /*- Replaced by direct adopt for WINNT support ---- 288 if( !CryptContextAddRef( aProv, NULL, NULL ) ) 289 throw Exception() ; 290 else 291 m_hProv = aProv ; 292 ----*/ 293 m_hProv = aProv ; 294 } 295 } 296 297 LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 298 return m_pszContainer ; 299 } 300 301 void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { 302 //TODO: Don't know whether or not it should be copied. 303 m_pszContainer = aKeyContainer ; 304 } 305 306 307 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) { 308 return m_hKeyStore ; 309 } 310 311 void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) { 312 if( m_hKeyStore != NULL ) { 313 CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 314 m_hKeyStore = NULL ; 315 } 316 317 if( aSlot != NULL ) { 318 m_hKeyStore = CertDuplicateStore( aSlot ) ; 319 } 320 } 321 322 HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) { 323 return m_hCertStore ; 324 } 325 326 void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) { 327 if( m_hCertStore != NULL ) { 328 CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; 329 m_hCertStore = NULL ; 330 } 331 332 if( aCertDb != NULL ) { 333 m_hCertStore = CertDuplicateStore( aCertDb ) ; 334 } 335 } 336 337 void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { 338 HCRYPTKEY symkey ; 339 std::list< HCRYPTKEY >::iterator keyIt ; 340 341 if( aSymKey != NULL ) { 342 //First try to find the key in the list 343 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) { 344 if( *keyIt == aSymKey ) 345 return ; 346 } 347 348 //If we do not find the key in the list, add a new node 349 /*- Replaced with directly adopt for WINNT 4.0 support ---- 350 if( !CryptDuplicateKey( aSymKey, NULL, 0, &symkey ) ) 351 throw RuntimeException() ; 352 ----*/ 353 symkey = aSymKey ; 354 355 try { 356 m_tSymKeyList.push_back( symkey ) ; 357 } catch ( Exception& ) { 358 CryptDestroyKey( symkey ) ; 359 } 360 } 361 } 362 363 void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { 364 HCRYPTKEY symkey ; 365 std::list< HCRYPTKEY >::iterator keyIt ; 366 367 if( aSymKey != NULL ) { 368 for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) { 369 if( *keyIt == aSymKey ) { 370 symkey = *keyIt ; 371 CryptDestroyKey( symkey ) ; 372 m_tSymKeyList.erase( keyIt ) ; 373 break ; 374 } 375 } 376 } 377 } 378 379 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) { 380 HCRYPTKEY symkey ; 381 std::list< HCRYPTKEY >::iterator keyIt ; 382 unsigned int pos ; 383 384 symkey = NULL ; 385 for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ; 386 387 if( pos == position && keyIt != m_tSymKeyList.end() ) 388 symkey = *keyIt ; 389 390 return symkey ; 391 } 392 393 void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { 394 HCRYPTKEY pubkey ; 395 std::list< HCRYPTKEY >::iterator keyIt ; 396 397 if( aPubKey != NULL ) { 398 //First try to find the key in the list 399 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) { 400 if( *keyIt == aPubKey ) 401 return ; 402 } 403 404 //If we do not find the key in the list, add a new node 405 /*- Replaced with directly adopt for WINNT 4.0 support ---- 406 if( !CryptDuplicateKey( aPubKey, NULL, 0, &pubkey ) ) 407 throw RuntimeException() ; 408 ----*/ 409 pubkey = aPubKey ; 410 411 try { 412 m_tPubKeyList.push_back( pubkey ) ; 413 } catch ( Exception& ) { 414 CryptDestroyKey( pubkey ) ; 415 } 416 } 417 } 418 419 void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { 420 HCRYPTKEY pubkey ; 421 std::list< HCRYPTKEY >::iterator keyIt ; 422 423 if( aPubKey != NULL ) { 424 for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) { 425 if( *keyIt == aPubKey ) { 426 pubkey = *keyIt ; 427 CryptDestroyKey( pubkey ) ; 428 m_tPubKeyList.erase( keyIt ) ; 429 break ; 430 } 431 } 432 } 433 } 434 435 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) { 436 HCRYPTKEY pubkey ; 437 std::list< HCRYPTKEY >::iterator keyIt ; 438 unsigned int pos ; 439 440 pubkey = NULL ; 441 for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ; 442 443 if( pos == position && keyIt != m_tPubKeyList.end() ) 444 pubkey = *keyIt ; 445 446 return pubkey ; 447 } 448 449 void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { 450 HCRYPTKEY prikey ; 451 std::list< HCRYPTKEY >::iterator keyIt ; 452 453 if( aPriKey != NULL ) { 454 //First try to find the key in the list 455 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) { 456 if( *keyIt == aPriKey ) 457 return ; 458 } 459 460 //If we do not find the key in the list, add a new node 461 /*- Replaced with directly adopt for WINNT 4.0 support ---- 462 if( !CryptDuplicateKey( aPriKey, NULL, 0, &prikey ) ) 463 throw RuntimeException() ; 464 ----*/ 465 prikey = aPriKey ; 466 467 try { 468 m_tPriKeyList.push_back( prikey ) ; 469 } catch ( Exception& ) { 470 CryptDestroyKey( prikey ) ; 471 } 472 } 473 } 474 475 void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { 476 HCRYPTKEY prikey ; 477 std::list< HCRYPTKEY >::iterator keyIt ; 478 479 if( aPriKey != NULL ) { 480 for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) { 481 if( *keyIt == aPriKey ) { 482 prikey = *keyIt ; 483 CryptDestroyKey( prikey ) ; 484 m_tPriKeyList.erase( keyIt ) ; 485 break ; 486 } 487 } 488 } 489 } 490 491 HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) { 492 HCRYPTKEY prikey ; 493 std::list< HCRYPTKEY >::iterator keyIt ; 494 unsigned int pos ; 495 496 prikey = NULL ; 497 for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ; 498 499 if( pos == position && keyIt != m_tPriKeyList.end() ) 500 prikey = *keyIt ; 501 502 return prikey ; 503 } 504 505 //Methods from XSecurityEnvironment 506 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException ) 507 { 508 sal_Int32 length ; 509 X509Certificate_MSCryptImpl* xcert ; 510 std::list< X509Certificate_MSCryptImpl* > certsList ; 511 PCCERT_CONTEXT pCertContext = NULL; 512 513 //firstly, we try to find private keys in given key store. 514 if( m_hKeyStore != NULL ) { 515 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ); 516 while (pCertContext) 517 { 518 xcert = MswcryCertContextToXCert( pCertContext ) ; 519 if( xcert != NULL ) 520 certsList.push_back( xcert ) ; 521 pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ); 522 } 523 } 524 525 //secondly, we try to find certificate from registered private keys. 526 if( !m_tPriKeyList.empty() ) { 527 //TODO: Don't know whether or not it is necessary ans possible. 528 } 529 530 //Thirdly, we try to find certificate from system default key store. 531 if( m_bEnableDefault ) { 532 HCERTSTORE hSystemKeyStore ; 533 DWORD dwKeySpec; 534 HCRYPTPROV hCryptProv; 535 536 /* 537 hSystemKeyStore = CertOpenStore( 538 CERT_STORE_PROV_SYSTEM , 539 0 , 540 NULL , 541 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG , 542 L"MY" 543 ) ; 544 */ 545 hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ; 546 if( hSystemKeyStore != NULL ) { 547 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 548 while (pCertContext) 549 { 550 // Add By CP for checking whether the certificate is a personal certificate or not. 551 if(!(CryptAcquireCertificatePrivateKey(pCertContext, 552 CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 553 NULL, 554 &hCryptProv, 555 &dwKeySpec, 556 NULL))) 557 { 558 // Not Privatekey found. SKIP this one; By CP 559 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 560 continue; 561 } 562 // then TODO : Check the personal cert is valid or not. 563 564 // end CP 565 xcert = MswcryCertContextToXCert( pCertContext ) ; 566 if( xcert != NULL ) 567 certsList.push_back( xcert ) ; 568 pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); 569 } 570 } 571 572 CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 573 } 574 575 length = certsList.size() ; 576 if( length != 0 ) { 577 int i ; 578 std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ; 579 Sequence< Reference< XCertificate > > certSeq( length ) ; 580 581 for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) { 582 certSeq[i] = *xcertIt ; 583 } 584 585 return certSeq ; 586 } 587 588 return Sequence< Reference< XCertificate > >() ; 589 } 590 591 592 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) { 593 unsigned int i ; 594 // sal_Int8 found = 0 ; 595 LPSTR pszName ; 596 X509Certificate_MSCryptImpl *xcert = NULL ; 597 PCCERT_CONTEXT pCertContext = NULL ; 598 HCERTSTORE hCertStore = NULL ; 599 CRYPT_INTEGER_BLOB cryptSerialNumber ; 600 CERT_INFO certInfo ; 601 602 // By CP , for correct encoding 603 sal_uInt16 encoding ; 604 rtl_Locale *pLocale = NULL ; 605 osl_getProcessLocale( &pLocale ) ; 606 encoding = osl_getTextEncodingFromLocale( pLocale ) ; 607 // CP end 608 609 //Create cert info from issue and serial 610 rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ; 611 pszName = ( char* )oissuer.getStr() ; 612 613 if( ! ( CertStrToName( 614 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 615 pszName , 616 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, 617 NULL , 618 NULL , 619 &certInfo.Issuer.cbData, NULL ) ) 620 ) { 621 return NULL ; 622 } 623 624 certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData ); 625 if(!certInfo.Issuer.pbData) 626 throw RuntimeException() ; 627 628 if( ! ( CertStrToName( 629 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 630 pszName , 631 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, 632 NULL , 633 ( BYTE* )certInfo.Issuer.pbData , 634 &certInfo.Issuer.cbData, NULL ) ) 635 ) { 636 free( certInfo.Issuer.pbData ) ; 637 return NULL ; 638 } 639 640 //Get the SerialNumber 641 cryptSerialNumber.cbData = serialNumber.getLength() ; 642 cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData); 643 if (!cryptSerialNumber.pbData) 644 { 645 free( certInfo.Issuer.pbData ) ; 646 throw RuntimeException() ; 647 } 648 for( i = 0; i < cryptSerialNumber.cbData; i ++ ) 649 cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ; 650 651 certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ; 652 certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ; 653 654 // Get the Cert from all store. 655 for( i = 0 ; i < 6 ; i ++ ) 656 { 657 switch(i) 658 { 659 case 0: 660 if(m_hKeyStore == NULL) continue ; 661 hCertStore = m_hKeyStore ; 662 break; 663 case 1: 664 if(m_hCertStore == NULL) continue ; 665 hCertStore = m_hCertStore ; 666 break; 667 case 2: 668 hCertStore = CertOpenSystemStore( 0, "MY" ) ; 669 if(hCertStore == NULL || !m_bEnableDefault) continue ; 670 break; 671 case 3: 672 hCertStore = CertOpenSystemStore( 0, "Root" ) ; 673 if(hCertStore == NULL || !m_bEnableDefault) continue ; 674 break; 675 case 4: 676 hCertStore = CertOpenSystemStore( 0, "Trust" ) ; 677 if(hCertStore == NULL || !m_bEnableDefault) continue ; 678 break; 679 case 5: 680 hCertStore = CertOpenSystemStore( 0, "CA" ) ; 681 if(hCertStore == NULL || !m_bEnableDefault) continue ; 682 break; 683 default: 684 i=6; 685 continue; 686 } 687 688 /******************************************************************************* 689 * This code reserved for remind us there are another way to find one cert by 690 * IssuerName&serialnumber. You can use the code to replaced the function 691 * CertFindCertificateInStore IF and ONLY IF you must find one special cert in 692 * certStore but can not be found by CertFindCertificateInStore , then , you 693 * should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875. 694 * By Chandler Peng(chandler.peng@sun.com) 695 *****/ 696 /******************************************************************************* 697 pCertContext = NULL ; 698 found = 0; 699 do{ 700 // 1. enum the certs has same string in the issuer string. 701 pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ; 702 if( pCertContext != NULL ) 703 { 704 // 2. check the cert's issuer name . 705 char* issuer = NULL ; 706 DWORD cbIssuer = 0 ; 707 708 cbIssuer = CertNameToStr( 709 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 710 &( pCertContext->pCertInfo->Issuer ), 711 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , 712 NULL, 0 713 ) ; 714 715 if( cbIssuer == 0 ) continue ; // discard this cert; 716 717 issuer = (char *)malloc( cbIssuer ) ; 718 if( issuer == NULL ) // discard this cert; 719 { 720 free( cryptSerialNumber.pbData) ; 721 free( certInfo.Issuer.pbData ) ; 722 CertFreeCertificateContext( pCertContext ) ; 723 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 724 throw RuntimeException() ; 725 } 726 727 cbIssuer = CertNameToStr( 728 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 729 &( pCertContext->pCertInfo->Issuer ), 730 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , 731 issuer, cbIssuer 732 ) ; 733 734 if( cbIssuer <= 0 ) 735 { 736 free( issuer ) ; 737 continue ;// discard this cert; 738 } 739 740 if(strncmp(pszName , issuer , cbIssuer) != 0) 741 { 742 free( issuer ) ; 743 continue ;// discard this cert; 744 } 745 free( issuer ) ; 746 747 // 3. check the serial number. 748 if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 ) 749 { 750 continue ;// discard this cert; 751 } 752 753 // 4. confirm and break; 754 found = 1; 755 break ; 756 } 757 758 }while(pCertContext); 759 760 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 761 if( found != 0 ) break; // Found the certificate. 762 ********************************************************************************/ 763 764 pCertContext = CertFindCertificateInStore( 765 hCertStore, 766 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 767 0, 768 CERT_FIND_SUBJECT_CERT, 769 &certInfo, 770 NULL 771 ) ; 772 773 if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 774 if( pCertContext != NULL ) break ; // Found the certificate. 775 776 } 777 778 if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ; 779 if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ; 780 781 if( pCertContext != NULL ) { 782 xcert = MswcryCertContextToXCert( pCertContext ) ; 783 if( pCertContext ) CertFreeCertificateContext( pCertContext ) ; 784 } else { 785 xcert = NULL ; 786 } 787 788 return xcert ; 789 } 790 791 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) { 792 Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ; 793 return getCertificate( issuerName, serial ) ; 794 } 795 796 Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) { 797 PCCERT_CHAIN_CONTEXT pChainContext ; 798 PCCERT_CONTEXT pCertContext ; 799 const X509Certificate_MSCryptImpl* xcert ; 800 801 CERT_ENHKEY_USAGE enhKeyUsage ; 802 CERT_USAGE_MATCH certUsage ; 803 CERT_CHAIN_PARA chainPara ; 804 805 enhKeyUsage.cUsageIdentifier = 0 ; 806 enhKeyUsage.rgpszUsageIdentifier = NULL ; 807 certUsage.dwType = USAGE_MATCH_TYPE_AND ; 808 certUsage.Usage = enhKeyUsage ; 809 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ; 810 chainPara.RequestedUsage = certUsage ; 811 812 Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ; 813 if( !xCertTunnel.is() ) { 814 throw RuntimeException() ; 815 } 816 817 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 818 if( xcert == NULL ) { 819 throw RuntimeException() ; 820 } 821 822 pCertContext = xcert->getMswcryCert() ; 823 824 pChainContext = NULL ; 825 826 BOOL bChain = FALSE; 827 if( pCertContext != NULL ) 828 { 829 HCERTSTORE hAdditionalStore = NULL; 830 HCERTSTORE hCollectionStore = NULL; 831 if (m_hCertStore && m_hKeyStore) 832 { 833 //Merge m_hCertStore and m_hKeyStore into one store. 834 hCollectionStore = CertOpenStore( 835 CERT_STORE_PROV_COLLECTION , 836 0 , 837 NULL , 838 0 , 839 NULL 840 ) ; 841 if (hCollectionStore != NULL) 842 { 843 CertAddStoreToCollection ( 844 hCollectionStore , 845 m_hCertStore , 846 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 847 0) ; 848 CertAddStoreToCollection ( 849 hCollectionStore , 850 m_hCertStore , 851 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 852 0) ; 853 hAdditionalStore = hCollectionStore; 854 } 855 856 } 857 858 //if the merge of both stores failed then we add only m_hCertStore 859 if (hAdditionalStore == NULL && m_hCertStore) 860 hAdditionalStore = m_hCertStore; 861 else if (hAdditionalStore == NULL && m_hKeyStore) 862 hAdditionalStore = m_hKeyStore; 863 else 864 hAdditionalStore = NULL; 865 866 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST 867 bChain = CertGetCertificateChain( 868 NULL , 869 pCertContext , 870 NULL , //use current system time 871 hAdditionalStore, 872 &chainPara , 873 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME , 874 NULL , 875 &pChainContext); 876 if (!bChain) 877 pChainContext = NULL; 878 879 //Close the additional store 880 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); 881 } 882 883 if(bChain && pChainContext != NULL && pChainContext->cChain > 0 ) 884 { 885 PCCERT_CONTEXT pCertInChain ; 886 PCERT_SIMPLE_CHAIN pCertChain ; 887 X509Certificate_MSCryptImpl* pCert ; 888 889 pCertChain = pChainContext->rgpChain[0] ; 890 if( pCertChain->cElement ) { 891 Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ; 892 893 for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) { 894 if( pCertChain->rgpElement[i] ) 895 pCertInChain = pCertChain->rgpElement[i]->pCertContext ; 896 else 897 pCertInChain = NULL ; 898 899 if( pCertInChain != NULL ) { 900 pCert = MswcryCertContextToXCert( pCertInChain ) ; 901 if( pCert != NULL ) 902 xCertChain[i] = pCert ; 903 } 904 } 905 906 CertFreeCertificateChain( pChainContext ) ; 907 pChainContext = NULL ; 908 909 return xCertChain ; 910 } 911 } 912 if (pChainContext) 913 CertFreeCertificateChain(pChainContext); 914 915 return Sequence< Reference < XCertificate > >(); 916 } 917 918 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) { 919 X509Certificate_MSCryptImpl* xcert ; 920 921 if( rawCertificate.getLength() > 0 ) { 922 xcert = new X509Certificate_MSCryptImpl() ; 923 if( xcert == NULL ) 924 throw RuntimeException() ; 925 926 xcert->setRawCert( rawCertificate ) ; 927 } else { 928 xcert = NULL ; 929 } 930 931 return xcert ; 932 } 933 934 Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) { 935 xmlChar* chCert ; 936 xmlSecSize certSize ; 937 938 rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ; 939 940 chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ; 941 942 certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ; 943 944 Sequence< sal_Int8 > rawCert( certSize ) ; 945 for( unsigned int i = 0 ; i < certSize ; i ++ ) 946 rawCert[i] = *( chCert + i ) ; 947 948 xmlFree( chCert ) ; 949 950 return createCertificateFromRaw( rawCert ) ; 951 } 952 953 954 HCERTSTORE getCertStoreForIntermediatCerts( 955 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts) 956 { 957 HCERTSTORE store = NULL; 958 store = CertOpenStore( 959 CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); 960 if (store == NULL) 961 return NULL; 962 963 for (int i = 0; i < seqCerts.getLength(); i++) 964 { 965 xmlsec_trace("Added temporary certificate: \n%s", 966 OUStringToOString(seqCerts[i]->getSubjectName(), 967 osl_getThreadTextEncoding()).getStr()); 968 969 970 Sequence<sal_Int8> data = seqCerts[i]->getEncoded(); 971 PCCERT_CONTEXT cert = CertCreateCertificateContext( 972 X509_ASN_ENCODING, ( const BYTE* )&data[0], data.getLength()); 973 //Adding the certificate creates a copy and not just increases the ref count 974 //Therefore we free later the certificate that we now add 975 CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, NULL); 976 CertFreeCertificateContext(cert); 977 } 978 return store; 979 } 980 981 //We return only valid or invalid, as long as the API documentation expresses 982 //explicitly that all validation steps are carried out even if one or several 983 //errors occur. See also 984 //https://wiki.openoffice.org/wiki/Certificate_Path_Validation#Validation_status 985 sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate( 986 const Reference< ::com::sun::star::security::XCertificate >& aCert, 987 const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts) 988 throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) 989 { 990 sal_Int32 validity = 0; 991 PCCERT_CHAIN_CONTEXT pChainContext = NULL; 992 PCCERT_CONTEXT pCertContext = NULL; 993 const X509Certificate_MSCryptImpl* xcert = NULL; 994 995 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; 996 if( !xCertTunnel.is() ) { 997 throw RuntimeException() ; 998 } 999 1000 xmlsec_trace("Start verification of certificate: \n %s", 1001 OUStringToOString( 1002 aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr()); 1003 1004 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 1005 if( xcert == NULL ) { 1006 throw RuntimeException() ; 1007 } 1008 1009 pCertContext = xcert->getMswcryCert() ; 1010 1011 CERT_ENHKEY_USAGE enhKeyUsage ; 1012 CERT_USAGE_MATCH certUsage ; 1013 CERT_CHAIN_PARA chainPara ; 1014 rtl_zeroMemory(&chainPara, sizeof(CERT_CHAIN_PARA)); 1015 1016 //Prepare parameter for CertGetCertificateChain 1017 enhKeyUsage.cUsageIdentifier = 0 ; 1018 enhKeyUsage.rgpszUsageIdentifier = NULL ; 1019 certUsage.dwType = USAGE_MATCH_TYPE_AND ; 1020 certUsage.Usage = enhKeyUsage ; 1021 chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ; 1022 chainPara.RequestedUsage = certUsage ; 1023 1024 1025 HCERTSTORE hCollectionStore = NULL; 1026 HCERTSTORE hIntermediateCertsStore = NULL; 1027 BOOL bChain = FALSE; 1028 if( pCertContext != NULL ) 1029 { 1030 hIntermediateCertsStore = 1031 getCertStoreForIntermediatCerts(seqCerts); 1032 1033 //Merge m_hCertStore and m_hKeyStore and the store of the intermediate 1034 //certificates into one store. 1035 hCollectionStore = CertOpenStore( 1036 CERT_STORE_PROV_COLLECTION , 1037 0 , 1038 NULL , 1039 0 , 1040 NULL 1041 ) ; 1042 if (hCollectionStore != NULL) 1043 { 1044 CertAddStoreToCollection ( 1045 hCollectionStore , 1046 m_hCertStore , 1047 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 1048 0) ; 1049 CertAddStoreToCollection ( 1050 hCollectionStore , 1051 m_hCertStore , 1052 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 1053 0) ; 1054 CertAddStoreToCollection ( 1055 hCollectionStore, 1056 hIntermediateCertsStore, 1057 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 1058 0); 1059 1060 } 1061 1062 //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST 1063 //We do not check revocation of the root. In most cases there are none. 1064 //Then we would get CERT_TRUST_REVOCATION_STATUS_UNKNOWN 1065 xmlsec_trace("Verifying cert using revocation information."); 1066 bChain = CertGetCertificateChain( 1067 NULL , 1068 pCertContext , 1069 NULL , //use current system time 1070 hCollectionStore, 1071 &chainPara , 1072 CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, 1073 NULL , 1074 &pChainContext); 1075 1076 if (bChain && pChainContext->cChain > 0) 1077 { 1078 xmlsec_trace("Overall error status (all chains):"); 1079 traceTrustStatus(pChainContext->TrustStatus.dwErrorStatus); 1080 //highest quality chains come first 1081 PCERT_SIMPLE_CHAIN pSimpleChain = pChainContext->rgpChain[0]; 1082 xmlsec_trace("Error status of first chain: "); 1083 traceTrustStatus(pSimpleChain->TrustStatus.dwErrorStatus); 1084 1085 //CERT_TRUST_REVOCATION_STATUS_UNKNOWN is also set if a certificate 1086 //has no AIA(OCSP) or CRLDP extension and there is no CRL locally installed. 1087 DWORD revocationFlags = CERT_TRUST_REVOCATION_STATUS_UNKNOWN | 1088 CERT_TRUST_IS_OFFLINE_REVOCATION; 1089 DWORD otherErrorsMask = ~revocationFlags; 1090 if( !(pSimpleChain->TrustStatus.dwErrorStatus & otherErrorsMask)) 1091 1092 { 1093 //No errors except maybe those caused by missing revocation information 1094 //Check if there are errors 1095 if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags) 1096 { 1097 //No revocation information. Because MSDN documentation is not 1098 //clear about if all other tests are performed if an error occurs, 1099 //we test again, without requiring revocation checking. 1100 CertFreeCertificateChain(pChainContext); 1101 pChainContext = NULL; 1102 xmlsec_trace("Checking again but without requiring revocation information."); 1103 bChain = CertGetCertificateChain( 1104 NULL , 1105 pCertContext , 1106 NULL , //use current system time 1107 hCollectionStore, 1108 &chainPara , 1109 0, 1110 NULL , 1111 &pChainContext); 1112 if (bChain 1113 && pChainContext->cChain > 0 1114 && pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) 1115 { 1116 xmlsec_trace("Certificate is valid.\n"); 1117 validity = ::com::sun::star::security::CertificateValidity::VALID; 1118 } 1119 else 1120 { 1121 xmlsec_trace("Certificate is invalid.\n"); 1122 } 1123 } 1124 else 1125 { 1126 //valid and revocation information available 1127 xmlsec_trace("Certificate is valid.\n"); 1128 validity = ::com::sun::star::security::CertificateValidity::VALID; 1129 } 1130 } 1131 else 1132 { 1133 //invalid 1134 xmlsec_trace("Certificate is invalid.\n"); 1135 validity = ::com::sun::star::security::CertificateValidity::INVALID ; 1136 } 1137 } 1138 else 1139 { 1140 xmlsec_trace("CertGetCertificateChaine failed.\n"); 1141 } 1142 } 1143 1144 if (pChainContext) 1145 { 1146 CertFreeCertificateChain(pChainContext); 1147 pChainContext = NULL; 1148 } 1149 1150 //Close the additional store, do not destroy the contained certs 1151 CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); 1152 //Close the temporary store containing the intermediate certificates and make 1153 //sure all certificates are deleted. 1154 CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG); 1155 1156 return validity ; 1157 } 1158 1159 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 ) { 1160 sal_Int32 characters ; 1161 PCCERT_CONTEXT pCertContext ; 1162 const X509Certificate_MSCryptImpl* xcert ; 1163 1164 Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; 1165 if( !xCertTunnel.is() ) { 1166 throw RuntimeException() ; 1167 } 1168 1169 xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; 1170 if( xcert == NULL ) { 1171 throw RuntimeException() ; 1172 } 1173 1174 pCertContext = xcert->getMswcryCert() ; 1175 1176 characters = 0x00000000 ; 1177 1178 //Firstly, make sentence whether or not the cert is self-signed. 1179 if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) { 1180 characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; 1181 } else { 1182 characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; 1183 } 1184 1185 //Secondly, make sentence whether or not the cert has a private key. 1186 { 1187 BOOL fCallerFreeProv ; 1188 DWORD dwKeySpec ; 1189 HCRYPTPROV hProv ; 1190 if( CryptAcquireCertificatePrivateKey( pCertContext , 1191 0 , 1192 NULL , 1193 &( hProv ) , 1194 &( dwKeySpec ) , 1195 &( fCallerFreeProv ) ) 1196 ) { 1197 characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; 1198 1199 if( hProv != NULL && fCallerFreeProv ) 1200 CryptReleaseContext( hProv, 0 ) ; 1201 } else { 1202 characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; 1203 } 1204 } 1205 return characters ; 1206 } 1207 1208 void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) { 1209 m_bEnableDefault = enable ; 1210 } 1211 1212 sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) { 1213 return m_bEnableDefault ; 1214 } 1215 1216 X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) 1217 { 1218 X509Certificate_MSCryptImpl* xcert ; 1219 1220 if( cert != NULL ) { 1221 xcert = new X509Certificate_MSCryptImpl() ; 1222 if( xcert != NULL ) { 1223 xcert->setMswcryCert( cert ) ; 1224 } 1225 } else { 1226 xcert = NULL ; 1227 } 1228 1229 return xcert ; 1230 } 1231 1232 ::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException ) 1233 { 1234 return rtl::OUString::createFromAscii("Microsoft Crypto API"); 1235 } 1236 1237 /* Native methods */ 1238 xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) { 1239 1240 unsigned int i ; 1241 HCRYPTKEY symKey ; 1242 HCRYPTKEY pubKey ; 1243 HCRYPTKEY priKey ; 1244 xmlSecKeysMngrPtr pKeysMngr = NULL ; 1245 1246 /*- 1247 * The following lines is based on the of xmlsec-mscrypto crypto engine 1248 */ 1249 pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ; 1250 if( pKeysMngr == NULL ) 1251 throw RuntimeException() ; 1252 1253 /*- 1254 * Adopt symmetric key into keys manager 1255 */ 1256 for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) { 1257 if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) { 1258 throw RuntimeException() ; 1259 } 1260 } 1261 1262 /*- 1263 * Adopt asymmetric public key into keys manager 1264 */ 1265 for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) { 1266 if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) { 1267 throw RuntimeException() ; 1268 } 1269 } 1270 1271 /*- 1272 * Adopt asymmetric private key into keys manager 1273 */ 1274 for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) { 1275 if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) { 1276 throw RuntimeException() ; 1277 } 1278 } 1279 1280 /*- 1281 * Adopt system default certificate store. 1282 */ 1283 if( defaultEnabled() ) { 1284 //Add system key store into the keys manager. 1285 m_hMySystemStore = CertOpenSystemStore( 0, "MY" ) ; 1286 if( m_hMySystemStore != NULL ) { 1287 if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, m_hMySystemStore ) < 0 ) { 1288 CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 1289 m_hMySystemStore = NULL; 1290 throw RuntimeException() ; 1291 } 1292 } 1293 1294 //Add system root store into the keys manager. 1295 m_hRootSystemStore = CertOpenSystemStore( 0, "Root" ) ; 1296 if( m_hRootSystemStore != NULL ) { 1297 if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, m_hRootSystemStore ) < 0 ) { 1298 CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 1299 m_hRootSystemStore = NULL; 1300 throw RuntimeException() ; 1301 } 1302 } 1303 1304 //Add system trusted store into the keys manager. 1305 m_hTrustSystemStore = CertOpenSystemStore( 0, "Trust" ) ; 1306 if( m_hTrustSystemStore != NULL ) { 1307 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hTrustSystemStore ) < 0 ) { 1308 CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 1309 m_hTrustSystemStore = NULL; 1310 throw RuntimeException() ; 1311 } 1312 } 1313 1314 //Add system CA store into the keys manager. 1315 m_hCaSystemStore = CertOpenSystemStore( 0, "CA" ) ; 1316 if( m_hCaSystemStore != NULL ) { 1317 if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hCaSystemStore ) < 0 ) { 1318 CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; 1319 m_hCaSystemStore = NULL; 1320 throw RuntimeException() ; 1321 } 1322 } 1323 } 1324 1325 return pKeysMngr ; 1326 } 1327 void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) { 1328 if( pKeysMngr != NULL ) { 1329 xmlSecKeysMngrDestroy( pKeysMngr ) ; 1330 } 1331 } 1332