1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
30 #include <sal/config.h>
31 #include <rtl/uuid.h>
32 #include "securityenvironment_mscryptimpl.hxx"
33 
34 #ifndef _XMLSECURITYCONTEXT_MSCRYPTIMPL_HXX_
35 #include "xmlsecuritycontext_mscryptimpl.hxx"
36 #endif
37 #include "xmlstreamio.hxx"
38 
39 #include "xmlsec/xmlsec.h"
40 #include "xmlsec/keysmngr.h"
41 #include "xmlsec/crypto.h"
42 #include "xmlsec/mscrypto/akmngr.h"
43 
44 using namespace ::com::sun::star::uno ;
45 using namespace ::com::sun::star::lang ;
46 using ::com::sun::star::lang::XMultiServiceFactory ;
47 using ::com::sun::star::lang::XSingleServiceFactory ;
48 using ::rtl::OUString ;
49 
50 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
51 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
52 
53 XMLSecurityContext_MSCryptImpl :: XMLSecurityContext_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory )
54 	://m_pKeysMngr( NULL ) ,
55 	 m_xServiceManager( aFactory ),
56 	 m_xSecurityEnvironment( NULL )
57 {
58 	//Init xmlsec library
59 	if( xmlSecInit() < 0 ) {
60 		throw RuntimeException() ;
61 	}
62 
63 	//Init xmlsec crypto engine library
64 	if( xmlSecCryptoInit() < 0 ) {
65 		xmlSecShutdown() ;
66 		throw RuntimeException() ;
67 	}
68 
69 	//Enable external stream handlers
70 	if( xmlEnableStreamInputCallbacks() < 0 ) {
71 		xmlSecCryptoShutdown() ;
72 		xmlSecShutdown() ;
73 		throw RuntimeException() ;
74 	}
75 }
76 
77 XMLSecurityContext_MSCryptImpl :: ~XMLSecurityContext_MSCryptImpl() {
78 	xmlDisableStreamInputCallbacks() ;
79 	xmlSecCryptoShutdown() ;
80 	xmlSecShutdown() ;
81 }
82 
83 //i39448 : new methods
84 sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::addSecurityEnvironment(
85 	const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment)
86 	throw (::com::sun::star::security::SecurityInfrastructureException, ::com::sun::star::uno::RuntimeException)
87 {
88 	if( !aSecurityEnvironment.is() )
89 	{
90 		throw RuntimeException() ;
91 	}
92 
93 	m_xSecurityEnvironment = aSecurityEnvironment;
94 
95 	return 0;
96 }
97 
98 
99 sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::getSecurityEnvironmentNumber(  )
100 	throw (::com::sun::star::uno::RuntimeException)
101 {
102 	return 1;
103 }
104 
105 ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL
106 	XMLSecurityContext_MSCryptImpl::getSecurityEnvironmentByIndex( sal_Int32 index )
107 	throw (::com::sun::star::uno::RuntimeException)
108 {
109 	if (index == 0)
110 	{
111 		return m_xSecurityEnvironment;
112 	}
113 	else
114 		throw RuntimeException() ;
115 }
116 
117 ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL
118 	XMLSecurityContext_MSCryptImpl::getSecurityEnvironment(  )
119 	throw (::com::sun::star::uno::RuntimeException)
120 {
121 	return m_xSecurityEnvironment;
122 }
123 
124 sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::getDefaultSecurityEnvironmentIndex(  )
125 	throw (::com::sun::star::uno::RuntimeException)
126 {
127 	return 0;
128 }
129 
130 void SAL_CALL XMLSecurityContext_MSCryptImpl::setDefaultSecurityEnvironmentIndex( sal_Int32 /*nDefaultEnvIndex*/ )
131 	throw (::com::sun::star::uno::RuntimeException)
132 {
133 	//dummy
134 }
135 
136 #if 0
137 /* XXMLSecurityContext */
138 void SAL_CALL XMLSecurityContext_MSCryptImpl :: setSecurityEnvironment( const Reference< XSecurityEnvironment >& aSecurityEnvironment ) throw( com::sun::star::security::SecurityInfrastructureException ) {
139 	HCERTSTORE hkeyStore ;
140 	HCERTSTORE hCertStore ;
141 	HCRYPTKEY symKey ;
142 	HCRYPTKEY pubKey ;
143 	HCRYPTKEY priKey ;
144 	unsigned int i ;
145 
146 	if( !aSecurityEnvironment.is() )
147 		throw RuntimeException() ;
148 
149 	m_xSecurityEnvironment = aSecurityEnvironment ;
150 
151 	//Clear key manager
152 	if( m_pKeysMngr != NULL ) {
153 		xmlSecKeysMngrDestroy( m_pKeysMngr ) ;
154 		m_pKeysMngr = NULL ;
155 	}
156 
157 	//Create key manager
158 	Reference< XUnoTunnel > xEnvTunnel( m_xSecurityEnvironment , UNO_QUERY ) ;
159 	if( !xEnvTunnel.is() ) {
160 		throw RuntimeException() ;
161 	}
162 
163 	SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xEnvTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
164 	if( pSecEnv == NULL )
165 		throw RuntimeException() ;
166 
167 	hkeyStore = pSecEnv->getCryptoSlot() ;
168 	hCertStore = pSecEnv->getCertDb() ;
169 
170 	/*-
171 	 * The following lines is based on the of xmlsec-mscrypto crypto engine
172 	 */
173 	m_pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( hkeyStore , hCertStore ) ;
174 	if( m_pKeysMngr == NULL )
175 		throw RuntimeException() ;
176 
177 	/*-
178 	 * Adopt symmetric key into keys manager
179 	 */
180 	for( i = 0 ; ( symKey = pSecEnv->getSymKey( i ) ) != NULL ; i ++ ) {
181 		if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( m_pKeysMngr, symKey ) < 0 ) {
182 			throw RuntimeException() ;
183 		}
184 	}
185 
186 	/*-
187 	 * Adopt asymmetric public key into keys manager
188 	 */
189 	for( i = 0 ; ( pubKey = pSecEnv->getPubKey( i ) ) != NULL ; i ++ ) {
190 		if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( m_pKeysMngr, pubKey ) < 0 ) {
191 			throw RuntimeException() ;
192 		}
193 	}
194 
195 	/*-
196 	 * Adopt asymmetric private key into keys manager
197 	 */
198 	for( i = 0 ; ( priKey = pSecEnv->getPriKey( i ) ) != NULL ; i ++ ) {
199 		if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( m_pKeysMngr, priKey ) < 0 ) {
200 			throw RuntimeException() ;
201 		}
202 	}
203 
204 	/*-
205 	 * Adopt system default certificate store.
206 	 */
207 	if( pSecEnv->defaultEnabled() ) {
208 		HCERTSTORE hSystemStore ;
209 
210 		//Add system key store into the keys manager.
211 		hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
212 		if( hSystemStore != NULL ) {
213 			if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( m_pKeysMngr, hSystemStore ) < 0 ) {
214 				CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
215 				throw RuntimeException() ;
216 			}
217 		}
218 
219 		//Add system root store into the keys manager.
220 		hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
221 		if( hSystemStore != NULL ) {
222 			if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) {
223 				CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
224 				throw RuntimeException() ;
225 			}
226 		}
227 
228 		//Add system trusted store into the keys manager.
229 		hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
230 		if( hSystemStore != NULL ) {
231 			if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) {
232 				CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
233 				throw RuntimeException() ;
234 			}
235 		}
236 
237 		//Add system CA store into the keys manager.
238 		hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
239 		if( hSystemStore != NULL ) {
240 			if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) {
241 				CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
242 				throw RuntimeException() ;
243 			}
244 		}
245 	}
246 }
247 
248 /* XXMLSecurityContext */
249 Reference< XSecurityEnvironment > SAL_CALL XMLSecurityContext_MSCryptImpl :: getSecurityEnvironment()
250 	throw (RuntimeException)
251 {
252 	return	m_xSecurityEnvironment ;
253 }
254 #endif
255 
256 /* XInitialization */
257 void SAL_CALL XMLSecurityContext_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
258 	// TBD
259 } ;
260 
261 /* XServiceInfo */
262 OUString SAL_CALL XMLSecurityContext_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
263 	return impl_getImplementationName() ;
264 }
265 
266 /* XServiceInfo */
267 sal_Bool SAL_CALL XMLSecurityContext_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
268 	Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
269 	const OUString* pArray = seqServiceNames.getConstArray() ;
270 	for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
271 		if( *( pArray + i ) == serviceName )
272 			return sal_True ;
273 	}
274 	return sal_False ;
275 }
276 
277 /* XServiceInfo */
278 Sequence< OUString > SAL_CALL XMLSecurityContext_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
279 	return impl_getSupportedServiceNames() ;
280 }
281 
282 //Helper for XServiceInfo
283 Sequence< OUString > XMLSecurityContext_MSCryptImpl :: impl_getSupportedServiceNames() {
284 	::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
285 	Sequence< OUString > seqServiceNames( 1 ) ;
286 	seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSecurityContext" ) ;
287 	return seqServiceNames ;
288 }
289 
290 OUString XMLSecurityContext_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
291 	return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_MSCryptImpl" ) ;
292 }
293 
294 //Helper for registry
295 Reference< XInterface > SAL_CALL XMLSecurityContext_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
296 	return Reference< XInterface >( *new XMLSecurityContext_MSCryptImpl( aServiceManager ) ) ;
297 }
298 
299 Reference< XSingleServiceFactory > XMLSecurityContext_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
300 	//Reference< XSingleServiceFactory > xFactory ;
301 	//xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
302 	//return xFactory ;
303 	return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
304 }
305 
306 #if 0
307 /* XUnoTunnel */
308 sal_Int64 SAL_CALL XMLSecurityContext_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
309 throw (RuntimeException)
310 {
311 	if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
312 		return ( sal_Int64 )this ;
313 	}
314 	return 0 ;
315 }
316 
317 /* XUnoTunnel extension */
318 const Sequence< sal_Int8>& XMLSecurityContext_MSCryptImpl :: getUnoTunnelId() {
319 	static Sequence< sal_Int8 >* pSeq = 0 ;
320 	if( !pSeq ) {
321 		::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
322 		if( !pSeq ) {
323 			static Sequence< sal_Int8> aSeq( 16 ) ;
324 			rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
325 			pSeq = &aSeq ;
326 		}
327 	}
328 	return *pSeq ;
329 }
330 
331 /* XUnoTunnel extension */
332 XMLSecurityContext_MSCryptImpl* XMLSecurityContext_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
333 	Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
334 	if( xUT.is() ) {
335 		return ( XMLSecurityContext_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
336 	} else
337 		return NULL ;
338 }
339 
340 /* Native methods */
341 xmlSecKeysMngrPtr XMLSecurityContext_MSCryptImpl :: keysManager() throw( Exception, RuntimeException ) {
342 	return m_pKeysMngr ;
343 }
344 #endif
345 
346