1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlencryption_mscryptimpl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #include <sal/config.h>
36 #include "xmlencryption_mscryptimpl.hxx"
38 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
39 #include "xmldocumentwrapper_xmlsecimpl.hxx"
42 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
43 #include "xmlelementwrapper_xmlsecimpl.hxx"
46 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
47 #include "securityenvironment_mscryptimpl.hxx"
49 #include "errorcallback.hxx"
51 #include "xmlsec/xmlsec.h"
52 #include "xmlsec/xmltree.h"
53 #include "xmlsec/xmlenc.h"
54 #include "xmlsec/crypto.h"
57 #define stricmp strcasecmp
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::lang
;
62 using ::com::sun::star::lang::XMultiServiceFactory
;
63 using ::com::sun::star::lang::XSingleServiceFactory
;
64 using ::rtl::OUString
;
66 using ::com::sun::star::xml::wrapper::XXMLElementWrapper
;
67 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper
;
68 using ::com::sun::star::xml::crypto::XSecurityEnvironment
;
69 using ::com::sun::star::xml::crypto::XXMLEncryption
;
70 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate
;
71 using ::com::sun::star::xml::crypto::XXMLSecurityContext
;
72 using ::com::sun::star::xml::crypto::XMLEncryptionException
;
74 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference
< XMultiServiceFactory
>& aFactory
) : m_xServiceManager( aFactory
) {
77 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
81 Reference
< XXMLEncryptionTemplate
>
82 SAL_CALL
XMLEncryption_MSCryptImpl :: encrypt(
83 const Reference
< XXMLEncryptionTemplate
>& aTemplate
,
84 const Reference
< XSecurityEnvironment
>& aEnvironment
85 ) throw( com::sun::star::xml::crypto::XMLEncryptionException
,
86 com::sun::star::uno::SecurityException
)
88 xmlSecKeysMngrPtr pMngr
= NULL
;
89 xmlSecEncCtxPtr pEncCtx
= NULL
;
90 xmlNodePtr pEncryptedData
= NULL
;
91 xmlNodePtr pContent
= NULL
;
94 throw RuntimeException() ;
96 if( !aEnvironment
.is() )
97 throw RuntimeException() ;
100 Reference
< XUnoTunnel
> xSecTunnel( aEnvironment
, UNO_QUERY
) ;
101 if( !xSecTunnel
.is() ) {
102 throw RuntimeException() ;
105 SecurityEnvironment_MSCryptImpl
* pSecEnv
= ( SecurityEnvironment_MSCryptImpl
* )xSecTunnel
->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
106 if( pSecEnv
== NULL
)
107 throw RuntimeException() ;
109 //Get the encryption template
110 Reference
< XXMLElementWrapper
> xTemplate
= aTemplate
->getTemplate() ;
111 if( !xTemplate
.is() ) {
112 throw RuntimeException() ;
115 Reference
< XUnoTunnel
> xTplTunnel( xTemplate
, UNO_QUERY
) ;
116 if( !xTplTunnel
.is() ) {
117 throw RuntimeException() ;
120 XMLElementWrapper_XmlSecImpl
* pTemplate
= ( XMLElementWrapper_XmlSecImpl
* )xTplTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
121 if( pTemplate
== NULL
) {
122 throw RuntimeException() ;
125 pEncryptedData
= pTemplate
->getNativeElement() ;
127 //Find the element to be encrypted.
128 //This element is wrapped in the CipherValue sub-element.
129 xmlNodePtr pCipherData
= pEncryptedData
->children
;
130 while (pCipherData
!= NULL
&& stricmp((const char *)(pCipherData
->name
), "CipherData"))
132 pCipherData
= pCipherData
->next
;
135 if( pCipherData
== NULL
) {
136 throw XMLEncryptionException() ;
139 xmlNodePtr pCipherValue
= pCipherData
->children
;
140 while (pCipherValue
!= NULL
&& stricmp((const char *)(pCipherValue
->name
), "CipherValue"))
142 pCipherValue
= pCipherValue
->next
;
145 if( pCipherValue
== NULL
) {
146 throw XMLEncryptionException() ;
149 pContent
= pCipherValue
->children
;
151 if( pContent
== NULL
) {
152 throw XMLEncryptionException() ;
155 xmlUnlinkNode(pContent
);
156 xmlAddNextSibling(pEncryptedData
, pContent
);
158 //remember the position of the element to be signed
159 sal_Bool isParentRef
= sal_True
;
160 xmlNodePtr pParent
= pEncryptedData
->parent
;
161 xmlNodePtr referenceNode
;
163 if (pEncryptedData
== pParent
->children
)
165 referenceNode
= pParent
;
169 referenceNode
= pEncryptedData
->prev
;
170 isParentRef
= sal_False
;
175 pMngr
= pSecEnv
->createKeysManager() ; //i39448
177 throw RuntimeException() ;
180 //Create Encryption context
181 pEncCtx
= xmlSecEncCtxCreate( pMngr
) ;
182 if( pEncCtx
== NULL
)
184 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
185 //throw XMLEncryptionException() ;
186 clearErrorRecorder();
190 //Encrypt the template
191 if( xmlSecEncCtxXmlEncrypt( pEncCtx
, pEncryptedData
, pContent
) < 0 ) {
192 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
193 xmlSecEncCtxDestroy( pEncCtx
) ;
194 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
195 clearErrorRecorder();
198 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
199 xmlSecEncCtxDestroy( pEncCtx
) ;
200 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
202 //get the new EncryptedData element
205 pTemplate
->setNativeElement(referenceNode
->children
) ;
209 pTemplate
->setNativeElement(referenceNode
->next
);
212 clearErrorRecorder();
217 Reference
< XXMLEncryptionTemplate
> SAL_CALL
218 XMLEncryption_MSCryptImpl :: decrypt(
219 const Reference
< XXMLEncryptionTemplate
>& aTemplate
,
220 const Reference
< XXMLSecurityContext
>& aSecurityCtx
221 ) throw( com::sun::star::xml::crypto::XMLEncryptionException
,
222 com::sun::star::uno::SecurityException
) {
223 xmlSecKeysMngrPtr pMngr
= NULL
;
224 xmlSecEncCtxPtr pEncCtx
= NULL
;
225 xmlNodePtr pEncryptedData
= NULL
;
227 if( !aTemplate
.is() )
228 throw RuntimeException() ;
230 if( !aSecurityCtx
.is() )
231 throw RuntimeException() ;
234 Reference
< XSecurityEnvironment
> xSecEnv
235 = aSecurityCtx
->getSecurityEnvironmentByIndex(
236 aSecurityCtx
->getDefaultSecurityEnvironmentIndex());
237 Reference
< XUnoTunnel
> xSecTunnel( xSecEnv
, UNO_QUERY
) ;
238 if( !xSecTunnel
.is() ) {
239 throw RuntimeException() ;
242 SecurityEnvironment_MSCryptImpl
* pSecEnv
= ( SecurityEnvironment_MSCryptImpl
* )xSecTunnel
->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
243 if( pSecEnv
== NULL
)
244 throw RuntimeException() ;
246 //Get the encryption template
247 Reference
< XXMLElementWrapper
> xTemplate
= aTemplate
->getTemplate() ;
248 if( !xTemplate
.is() ) {
249 throw RuntimeException() ;
252 Reference
< XUnoTunnel
> xTplTunnel( xTemplate
, UNO_QUERY
) ;
253 if( !xTplTunnel
.is() ) {
254 throw RuntimeException() ;
257 XMLElementWrapper_XmlSecImpl
* pTemplate
= ( XMLElementWrapper_XmlSecImpl
* )xTplTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
258 if( pTemplate
== NULL
) {
259 throw RuntimeException() ;
262 pEncryptedData
= pTemplate
->getNativeElement() ;
264 //remember the position of the element to be signed
265 sal_Bool isParentRef
= sal_True
;
266 xmlNodePtr pParent
= pEncryptedData
->parent
;
267 xmlNodePtr referenceNode
;
269 if (pEncryptedData
== pParent
->children
)
271 referenceNode
= pParent
;
275 referenceNode
= pEncryptedData
->prev
;
276 isParentRef
= sal_False
;
281 pMngr
= pSecEnv
->createKeysManager() ; //i39448
283 throw RuntimeException() ;
286 //Create Encryption context
287 pEncCtx
= xmlSecEncCtxCreate( pMngr
) ;
288 if( pEncCtx
== NULL
)
290 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
291 //throw XMLEncryptionException() ;
292 clearErrorRecorder();
296 //Decrypt the template
297 if( xmlSecEncCtxDecrypt( pEncCtx
, pEncryptedData
) < 0 || pEncCtx
->result
== NULL
) {
298 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
299 xmlSecEncCtxDestroy( pEncCtx
) ;
300 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
302 //throw XMLEncryptionException() ;
303 clearErrorRecorder();
306 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
307 /*----------------------------------------
308 if( pEncCtx->resultReplaced != 0 ) {
309 pContent = pEncryptedData ;
311 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
312 if( !xTunnel.is() ) {
313 xmlSecEncCtxDestroy( pEncCtx ) ;
314 throw RuntimeException() ;
316 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
317 if( pNode == NULL ) {
318 xmlSecEncCtxDestroy( pEncCtx ) ;
319 throw RuntimeException() ;
322 pNode->setNativeElement( pContent ) ;
324 xmlSecEncCtxDestroy( pEncCtx ) ;
325 throw RuntimeException() ;
327 ----------------------------------------*/
329 //Destroy the encryption context
330 xmlSecEncCtxDestroy( pEncCtx
) ;
331 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
333 //get the decrypted element
334 XMLElementWrapper_XmlSecImpl
* ret
= new XMLElementWrapper_XmlSecImpl(isParentRef
?
335 (referenceNode
->children
):(referenceNode
->next
));
338 aTemplate
->setTemplate(ret
);
340 clearErrorRecorder();
344 /* XInitialization */
345 void SAL_CALL
XMLEncryption_MSCryptImpl :: initialize( const Sequence
< Any
>& /*aArguments*/ ) throw( Exception
, RuntimeException
) {
350 OUString SAL_CALL
XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException
) {
351 return impl_getImplementationName() ;
355 sal_Bool SAL_CALL
XMLEncryption_MSCryptImpl :: supportsService( const OUString
& serviceName
) throw( RuntimeException
) {
356 Sequence
< OUString
> seqServiceNames
= getSupportedServiceNames() ;
357 const OUString
* pArray
= seqServiceNames
.getConstArray() ;
358 for( sal_Int32 i
= 0 ; i
< seqServiceNames
.getLength() ; i
++ ) {
359 if( *( pArray
+ i
) == serviceName
)
366 Sequence
< OUString
> SAL_CALL
XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException
) {
367 return impl_getSupportedServiceNames() ;
370 //Helper for XServiceInfo
371 Sequence
< OUString
> XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() {
372 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() ) ;
373 Sequence
< OUString
> seqServiceNames( 1 ) ;
374 seqServiceNames
.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
375 return seqServiceNames
;
378 OUString
XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException
) {
379 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ;
382 //Helper for registry
383 Reference
< XInterface
> SAL_CALL
XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference
< XMultiServiceFactory
>& aServiceManager
) throw( RuntimeException
) {
384 return Reference
< XInterface
>( *new XMLEncryption_MSCryptImpl( aServiceManager
) ) ;
387 Reference
< XSingleServiceFactory
> XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference
< XMultiServiceFactory
>& aServiceManager
) {
388 //Reference< XSingleServiceFactory > xFactory ;
389 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
391 return ::cppu::createSingleFactory( aServiceManager
, impl_getImplementationName() , impl_createInstance
, impl_getSupportedServiceNames() ) ;