xref: /AOO41X/main/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlsecurity.hxx"
26 #include <sal/config.h>
27 #include <rtl/uuid.h>
28 
29 #include "com/sun/star/xml/crypto/SecurityOperationStatus.hdl"
30 #include "xmlsignature_mscryptimpl.hxx"
31 
32 #ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
33 #include "xmldocumentwrapper_xmlsecimpl.hxx"
34 #endif
35 
36 #ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
37 #include "xmlelementwrapper_xmlsecimpl.hxx"
38 #endif
39 
40 #ifndef _SECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
41 #include "securityenvironment_mscryptimpl.hxx"
42 #endif
43 #include "xmlstreamio.hxx"
44 #include "errorcallback.hxx"
45 
46 #include "xmlsec/xmlsec.h"
47 #include "xmlsec/xmldsig.h"
48 #include "xmlsec/crypto.h"
49 
50 using namespace ::com::sun::star::uno ;
51 using namespace ::com::sun::star::lang ;
52 using ::com::sun::star::lang::XMultiServiceFactory ;
53 using ::com::sun::star::lang::XSingleServiceFactory ;
54 using ::rtl::OUString ;
55 
56 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
57 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
58 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
59 using ::com::sun::star::xml::crypto::XXMLSignature ;
60 using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ;
61 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
62 using ::com::sun::star::xml::crypto::XUriBinding ;
63 using ::com::sun::star::xml::crypto::XMLSignatureException ;
64 
65 
XMLSignature_MSCryptImpl(const Reference<XMultiServiceFactory> & aFactory)66 XMLSignature_MSCryptImpl :: XMLSignature_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
67 }
68 
~XMLSignature_MSCryptImpl()69 XMLSignature_MSCryptImpl :: ~XMLSignature_MSCryptImpl() {
70 }
71 
72 /* XXMLSignature */
73 Reference< XXMLSignatureTemplate >
generate(const Reference<XXMLSignatureTemplate> & aTemplate,const Reference<XSecurityEnvironment> & aEnvironment)74 SAL_CALL XMLSignature_MSCryptImpl :: generate(
75     const Reference< XXMLSignatureTemplate >& aTemplate ,
76     const Reference< XSecurityEnvironment >& aEnvironment
77 ) throw( com::sun::star::xml::crypto::XMLSignatureException,
78          com::sun::star::uno::SecurityException )
79 {
80     xmlSecKeysMngrPtr pMngr = NULL ;
81     xmlSecDSigCtxPtr pDsigCtx = NULL ;
82     xmlNodePtr pNode = NULL ;
83 
84     if( !aTemplate.is() )
85         throw RuntimeException() ;
86 
87     if( !aEnvironment.is() )
88         throw RuntimeException() ;
89 
90     //Get Keys Manager
91     Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
92     if( !xSecTunnel.is() ) {
93          throw RuntimeException() ;
94     }
95 
96     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
97     if( pSecEnv == NULL )
98         throw RuntimeException() ;
99 
100     //Get the xml node
101     Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
102     if( !xElement.is() ) {
103         throw RuntimeException() ;
104     }
105 
106     Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
107     if( !xNodTunnel.is() ) {
108         throw RuntimeException() ;
109     }
110 
111     XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
112     if( pElement == NULL ) {
113         throw RuntimeException() ;
114     }
115 
116     pNode = pElement->getNativeElement() ;
117 
118     //Get the stream/URI binding
119     Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
120     if( xUriBinding.is() ) {
121         //Register the stream input callbacks into libxml2
122         if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
123             throw RuntimeException() ;
124     }
125 
126     setErrorRecorder( );
127 
128     pMngr = pSecEnv->createKeysManager() ; //i39448
129     if( !pMngr ) {
130         throw RuntimeException() ;
131     }
132 
133     //Create Signature context
134     pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
135     if( pDsigCtx == NULL )
136     {
137         //throw XMLSignatureException() ;
138         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
139         clearErrorRecorder();
140         return aTemplate;
141     }
142 
143     //Sign the template
144     if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 )
145     {
146         if (pDsigCtx->status == xmlSecDSigStatusSucceeded)
147             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
148         else
149             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
150     }
151     else
152     {
153         aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
154     }
155 
156 
157     xmlSecDSigCtxDestroy( pDsigCtx ) ;
158     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
159 
160     //Unregistered the stream/URI binding
161     if( xUriBinding.is() )
162         xmlUnregisterStreamInputCallbacks() ;
163 
164     clearErrorRecorder();
165     return aTemplate ;
166 }
167 
168 /* XXMLSignature */
169 Reference< XXMLSignatureTemplate >
validate(const Reference<XXMLSignatureTemplate> & aTemplate,const Reference<XXMLSecurityContext> & aSecurityCtx)170 SAL_CALL XMLSignature_MSCryptImpl :: validate(
171     const Reference< XXMLSignatureTemplate >& aTemplate ,
172     const Reference< XXMLSecurityContext >& aSecurityCtx
173 ) throw( com::sun::star::uno::RuntimeException,
174          com::sun::star::uno::SecurityException,
175          com::sun::star::xml::crypto::XMLSignatureException ) {
176     xmlSecKeysMngrPtr pMngr = NULL ;
177     xmlSecDSigCtxPtr pDsigCtx = NULL ;
178     xmlNodePtr pNode = NULL ;
179     //sal_Bool valid ;
180 
181     if( !aTemplate.is() )
182         throw RuntimeException() ;
183 
184     if( !aSecurityCtx.is() )
185         throw RuntimeException() ;
186 
187     //Get Keys Manager
188     Reference< XSecurityEnvironment > xSecEnv
189         = aSecurityCtx->getSecurityEnvironmentByIndex(
190             aSecurityCtx->getDefaultSecurityEnvironmentIndex());
191     Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ;
192     if( !xSecTunnel.is() ) {
193          throw RuntimeException() ;
194     }
195 
196     SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
197     if( pSecEnv == NULL )
198         throw RuntimeException() ;
199 
200     //Get the xml node
201     Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
202     if( !xElement.is() )
203         throw RuntimeException() ;
204 
205     Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
206     if( !xNodTunnel.is() ) {
207         throw RuntimeException() ;
208     }
209 
210     XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
211     if( pElement == NULL )
212         throw RuntimeException() ;
213 
214     pNode = pElement->getNativeElement() ;
215 
216     //Get the stream/URI binding
217     Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
218     if( xUriBinding.is() ) {
219         //Register the stream input callbacks into libxml2
220         if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
221             throw RuntimeException() ;
222     }
223 
224     //added for test: save the result
225     /*
226     {
227         FILE *dstFile = fopen( "c:\\1.txt", "w" ) ;
228         xmlDocDump( dstFile, pNode->doc) ;
229         fclose( dstFile ) ;
230     }
231     */
232 
233     setErrorRecorder( );
234 
235     pMngr = pSecEnv->createKeysManager() ; //i39448
236     if( !pMngr ) {
237         throw RuntimeException() ;
238     }
239 
240     //Create Signature context
241     pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
242     if( pDsigCtx == NULL )
243     {
244         pSecEnv->destroyKeysManager( pMngr ) ; //i39448
245         //throw XMLSignatureException() ;
246         clearErrorRecorder();
247         return aTemplate;
248     }
249 
250     //Verify signature
251     //The documentation says that the signature is only valid if the return value is 0 (that is, not < 0)
252     //AND pDsigCtx->status == xmlSecDSigStatusSucceeded. That is, we must not make any assumptions, if
253     //the return value is < 0. Then we must regard the signature as INVALID. We cannot use the
254     //error recorder feature to get the ONE error that made the verification fail, because there is no
255     //documentation/specification as to how to interpret the number of recorded errors and what is the initial
256     //error.
257     if( xmlSecDSigCtxVerify( pDsigCtx , pNode ) == 0 )
258     {
259         if (pDsigCtx->status == xmlSecDSigStatusSucceeded)
260             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
261         else
262             aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
263     }
264     else
265     {
266         aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
267     }
268 
269     xmlSecDSigCtxDestroy( pDsigCtx ) ;
270     pSecEnv->destroyKeysManager( pMngr ) ; //i39448
271 
272     //Unregistered the stream/URI binding
273     if( xUriBinding.is() )
274         xmlUnregisterStreamInputCallbacks() ;
275 
276 
277     clearErrorRecorder();
278     return aTemplate;
279 }
280 
281 /* XInitialization */
initialize(const Sequence<Any> &)282 void SAL_CALL XMLSignature_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
283     // TBD
284 } ;
285 
286 /* XServiceInfo */
getImplementationName()287 OUString SAL_CALL XMLSignature_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
288     return impl_getImplementationName() ;
289 }
290 
291 /* XServiceInfo */
supportsService(const OUString & serviceName)292 sal_Bool SAL_CALL XMLSignature_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
293     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
294     const OUString* pArray = seqServiceNames.getConstArray() ;
295     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
296         if( *( pArray + i ) == serviceName )
297             return sal_True ;
298     }
299     return sal_False ;
300 }
301 
302 /* XServiceInfo */
getSupportedServiceNames()303 Sequence< OUString > SAL_CALL XMLSignature_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
304     return impl_getSupportedServiceNames() ;
305 }
306 
307 //Helper for XServiceInfo
impl_getSupportedServiceNames()308 Sequence< OUString > XMLSignature_MSCryptImpl :: impl_getSupportedServiceNames() {
309     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
310     Sequence< OUString > seqServiceNames( 1 ) ;
311     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ;
312     return seqServiceNames ;
313 }
314 
impl_getImplementationName()315 OUString XMLSignature_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
316     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_MSCryptImpl" ) ;
317 }
318 
319 //Helper for registry
impl_createInstance(const Reference<XMultiServiceFactory> & aServiceManager)320 Reference< XInterface > SAL_CALL XMLSignature_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
321     return Reference< XInterface >( *new XMLSignature_MSCryptImpl( aServiceManager ) ) ;
322 }
323 
impl_createFactory(const Reference<XMultiServiceFactory> & aServiceManager)324 Reference< XSingleServiceFactory > XMLSignature_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
325     //Reference< XSingleServiceFactory > xFactory ;
326     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
327     //return xFactory ;
328     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
329 }
330 
331