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