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