1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include <sal/config.h>
33 #include "xmlencryption_mscryptimpl.hxx"
35 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
36 #include "xmldocumentwrapper_xmlsecimpl.hxx"
39 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
40 #include "xmlelementwrapper_xmlsecimpl.hxx"
43 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
44 #include "securityenvironment_mscryptimpl.hxx"
46 #include "errorcallback.hxx"
48 #include "xmlsec/xmlsec.h"
49 #include "xmlsec/xmltree.h"
50 #include "xmlsec/xmlenc.h"
51 #include "xmlsec/crypto.h"
54 #define stricmp strcasecmp
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::lang
;
59 using ::com::sun::star::lang::XMultiServiceFactory
;
60 using ::com::sun::star::lang::XSingleServiceFactory
;
61 using ::rtl::OUString
;
63 using ::com::sun::star::xml::wrapper::XXMLElementWrapper
;
64 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper
;
65 using ::com::sun::star::xml::crypto::XSecurityEnvironment
;
66 using ::com::sun::star::xml::crypto::XXMLEncryption
;
67 using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate
;
68 using ::com::sun::star::xml::crypto::XXMLSecurityContext
;
69 using ::com::sun::star::xml::crypto::XMLEncryptionException
;
71 XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference
< XMultiServiceFactory
>& aFactory
) : m_xServiceManager( aFactory
) {
74 XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() {
78 Reference
< XXMLEncryptionTemplate
>
79 SAL_CALL
XMLEncryption_MSCryptImpl :: encrypt(
80 const Reference
< XXMLEncryptionTemplate
>& aTemplate
,
81 const Reference
< XSecurityEnvironment
>& aEnvironment
82 ) throw( com::sun::star::xml::crypto::XMLEncryptionException
,
83 com::sun::star::uno::SecurityException
)
85 xmlSecKeysMngrPtr pMngr
= NULL
;
86 xmlSecEncCtxPtr pEncCtx
= NULL
;
87 xmlNodePtr pEncryptedData
= NULL
;
88 xmlNodePtr pContent
= NULL
;
91 throw RuntimeException() ;
93 if( !aEnvironment
.is() )
94 throw RuntimeException() ;
97 Reference
< XUnoTunnel
> xSecTunnel( aEnvironment
, UNO_QUERY
) ;
98 if( !xSecTunnel
.is() ) {
99 throw RuntimeException() ;
102 SecurityEnvironment_MSCryptImpl
* pSecEnv
= ( SecurityEnvironment_MSCryptImpl
* )xSecTunnel
->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
103 if( pSecEnv
== NULL
)
104 throw RuntimeException() ;
106 //Get the encryption template
107 Reference
< XXMLElementWrapper
> xTemplate
= aTemplate
->getTemplate() ;
108 if( !xTemplate
.is() ) {
109 throw RuntimeException() ;
112 Reference
< XUnoTunnel
> xTplTunnel( xTemplate
, UNO_QUERY
) ;
113 if( !xTplTunnel
.is() ) {
114 throw RuntimeException() ;
117 XMLElementWrapper_XmlSecImpl
* pTemplate
= ( XMLElementWrapper_XmlSecImpl
* )xTplTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
118 if( pTemplate
== NULL
) {
119 throw RuntimeException() ;
122 pEncryptedData
= pTemplate
->getNativeElement() ;
124 //Find the element to be encrypted.
125 //This element is wrapped in the CipherValue sub-element.
126 xmlNodePtr pCipherData
= pEncryptedData
->children
;
127 while (pCipherData
!= NULL
&& stricmp((const char *)(pCipherData
->name
), "CipherData"))
129 pCipherData
= pCipherData
->next
;
132 if( pCipherData
== NULL
) {
133 throw XMLEncryptionException() ;
136 xmlNodePtr pCipherValue
= pCipherData
->children
;
137 while (pCipherValue
!= NULL
&& stricmp((const char *)(pCipherValue
->name
), "CipherValue"))
139 pCipherValue
= pCipherValue
->next
;
142 if( pCipherValue
== NULL
) {
143 throw XMLEncryptionException() ;
146 pContent
= pCipherValue
->children
;
148 if( pContent
== NULL
) {
149 throw XMLEncryptionException() ;
152 xmlUnlinkNode(pContent
);
153 xmlAddNextSibling(pEncryptedData
, pContent
);
155 //remember the position of the element to be signed
156 sal_Bool isParentRef
= sal_True
;
157 xmlNodePtr pParent
= pEncryptedData
->parent
;
158 xmlNodePtr referenceNode
;
160 if (pEncryptedData
== pParent
->children
)
162 referenceNode
= pParent
;
166 referenceNode
= pEncryptedData
->prev
;
167 isParentRef
= sal_False
;
172 pMngr
= pSecEnv
->createKeysManager() ; //i39448
174 throw RuntimeException() ;
177 //Create Encryption context
178 pEncCtx
= xmlSecEncCtxCreate( pMngr
) ;
179 if( pEncCtx
== NULL
)
181 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
182 //throw XMLEncryptionException() ;
183 clearErrorRecorder();
187 //Encrypt the template
188 if( xmlSecEncCtxXmlEncrypt( pEncCtx
, pEncryptedData
, pContent
) < 0 ) {
189 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
190 xmlSecEncCtxDestroy( pEncCtx
) ;
191 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
192 clearErrorRecorder();
195 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
196 xmlSecEncCtxDestroy( pEncCtx
) ;
197 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
199 //get the new EncryptedData element
202 pTemplate
->setNativeElement(referenceNode
->children
) ;
206 pTemplate
->setNativeElement(referenceNode
->next
);
209 clearErrorRecorder();
214 Reference
< XXMLEncryptionTemplate
> SAL_CALL
215 XMLEncryption_MSCryptImpl :: decrypt(
216 const Reference
< XXMLEncryptionTemplate
>& aTemplate
,
217 const Reference
< XXMLSecurityContext
>& aSecurityCtx
218 ) throw( com::sun::star::xml::crypto::XMLEncryptionException
,
219 com::sun::star::uno::SecurityException
) {
220 xmlSecKeysMngrPtr pMngr
= NULL
;
221 xmlSecEncCtxPtr pEncCtx
= NULL
;
222 xmlNodePtr pEncryptedData
= NULL
;
224 if( !aTemplate
.is() )
225 throw RuntimeException() ;
227 if( !aSecurityCtx
.is() )
228 throw RuntimeException() ;
231 Reference
< XSecurityEnvironment
> xSecEnv
232 = aSecurityCtx
->getSecurityEnvironmentByIndex(
233 aSecurityCtx
->getDefaultSecurityEnvironmentIndex());
234 Reference
< XUnoTunnel
> xSecTunnel( xSecEnv
, UNO_QUERY
) ;
235 if( !xSecTunnel
.is() ) {
236 throw RuntimeException() ;
239 SecurityEnvironment_MSCryptImpl
* pSecEnv
= ( SecurityEnvironment_MSCryptImpl
* )xSecTunnel
->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
240 if( pSecEnv
== NULL
)
241 throw RuntimeException() ;
243 //Get the encryption template
244 Reference
< XXMLElementWrapper
> xTemplate
= aTemplate
->getTemplate() ;
245 if( !xTemplate
.is() ) {
246 throw RuntimeException() ;
249 Reference
< XUnoTunnel
> xTplTunnel( xTemplate
, UNO_QUERY
) ;
250 if( !xTplTunnel
.is() ) {
251 throw RuntimeException() ;
254 XMLElementWrapper_XmlSecImpl
* pTemplate
= ( XMLElementWrapper_XmlSecImpl
* )xTplTunnel
->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
255 if( pTemplate
== NULL
) {
256 throw RuntimeException() ;
259 pEncryptedData
= pTemplate
->getNativeElement() ;
261 //remember the position of the element to be signed
262 sal_Bool isParentRef
= sal_True
;
263 xmlNodePtr pParent
= pEncryptedData
->parent
;
264 xmlNodePtr referenceNode
;
266 if (pEncryptedData
== pParent
->children
)
268 referenceNode
= pParent
;
272 referenceNode
= pEncryptedData
->prev
;
273 isParentRef
= sal_False
;
278 pMngr
= pSecEnv
->createKeysManager() ; //i39448
280 throw RuntimeException() ;
283 //Create Encryption context
284 pEncCtx
= xmlSecEncCtxCreate( pMngr
) ;
285 if( pEncCtx
== NULL
)
287 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
288 //throw XMLEncryptionException() ;
289 clearErrorRecorder();
293 //Decrypt the template
294 if( xmlSecEncCtxDecrypt( pEncCtx
, pEncryptedData
) < 0 || pEncCtx
->result
== NULL
) {
295 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN
);
296 xmlSecEncCtxDestroy( pEncCtx
) ;
297 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
299 //throw XMLEncryptionException() ;
300 clearErrorRecorder();
303 aTemplate
->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
304 /*----------------------------------------
305 if( pEncCtx->resultReplaced != 0 ) {
306 pContent = pEncryptedData ;
308 Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ;
309 if( !xTunnel.is() ) {
310 xmlSecEncCtxDestroy( pEncCtx ) ;
311 throw RuntimeException() ;
313 XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
314 if( pNode == NULL ) {
315 xmlSecEncCtxDestroy( pEncCtx ) ;
316 throw RuntimeException() ;
319 pNode->setNativeElement( pContent ) ;
321 xmlSecEncCtxDestroy( pEncCtx ) ;
322 throw RuntimeException() ;
324 ----------------------------------------*/
326 //Destroy the encryption context
327 xmlSecEncCtxDestroy( pEncCtx
) ;
328 pSecEnv
->destroyKeysManager( pMngr
) ; //i39448
330 //get the decrypted element
331 XMLElementWrapper_XmlSecImpl
* ret
= new XMLElementWrapper_XmlSecImpl(isParentRef
?
332 (referenceNode
->children
):(referenceNode
->next
));
335 aTemplate
->setTemplate(ret
);
337 clearErrorRecorder();
341 /* XInitialization */
342 void SAL_CALL
XMLEncryption_MSCryptImpl :: initialize( const Sequence
< Any
>& /*aArguments*/ ) throw( Exception
, RuntimeException
) {
347 OUString SAL_CALL
XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException
) {
348 return impl_getImplementationName() ;
352 sal_Bool SAL_CALL
XMLEncryption_MSCryptImpl :: supportsService( const OUString
& serviceName
) throw( RuntimeException
) {
353 Sequence
< OUString
> seqServiceNames
= getSupportedServiceNames() ;
354 const OUString
* pArray
= seqServiceNames
.getConstArray() ;
355 for( sal_Int32 i
= 0 ; i
< seqServiceNames
.getLength() ; i
++ ) {
356 if( *( pArray
+ i
) == serviceName
)
363 Sequence
< OUString
> SAL_CALL
XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException
) {
364 return impl_getSupportedServiceNames() ;
367 //Helper for XServiceInfo
368 Sequence
< OUString
> XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() {
369 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() ) ;
370 Sequence
< OUString
> seqServiceNames( 1 ) ;
371 seqServiceNames
.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLEncryption" ) ;
372 return seqServiceNames
;
375 OUString
XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException
) {
376 return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl" ) ;
379 //Helper for registry
380 Reference
< XInterface
> SAL_CALL
XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference
< XMultiServiceFactory
>& aServiceManager
) throw( RuntimeException
) {
381 return Reference
< XInterface
>( *new XMLEncryption_MSCryptImpl( aServiceManager
) ) ;
384 Reference
< XSingleServiceFactory
> XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference
< XMultiServiceFactory
>& aServiceManager
) {
385 //Reference< XSingleServiceFactory > xFactory ;
386 //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
388 return ::cppu::createSingleFactory( aServiceManager
, impl_getImplementationName() , impl_createInstance
, impl_getSupportedServiceNames() ) ;