Bump version to 5.0-14
[LibreOffice.git] / xmlsecurity / source / xmlsec / mscrypt / xmlsignature_mscryptimpl.cxx
blob939704f60d346c7f3bb68a5c8bcc6e17b118a9d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <rtl/uuid.h>
23 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
24 #include "xmlsignature_mscryptimpl.hxx"
25 #include "xmldocumentwrapper_xmlsecimpl.hxx"
26 #include "xmlelementwrapper_xmlsecimpl.hxx"
27 #include "securityenvironment_mscryptimpl.hxx"
28 #include "xmlstreamio.hxx"
29 #include "errorcallback.hxx"
30 #include "xmlsecurity/xmlsec-wrapper.h"
32 using namespace ::com::sun::star::uno ;
33 using namespace ::com::sun::star::lang ;
34 using ::com::sun::star::lang::XMultiServiceFactory ;
35 using ::com::sun::star::lang::XSingleServiceFactory ;
37 using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
38 using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
39 using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
40 using ::com::sun::star::xml::crypto::XXMLSignature ;
41 using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ;
42 using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
43 using ::com::sun::star::xml::crypto::XUriBinding ;
44 using ::com::sun::star::xml::crypto::XMLSignatureException ;
47 XMLSignature_MSCryptImpl :: XMLSignature_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
50 XMLSignature_MSCryptImpl :: ~XMLSignature_MSCryptImpl() {
53 /* XXMLSignature */
54 Reference< XXMLSignatureTemplate >
55 SAL_CALL XMLSignature_MSCryptImpl :: generate(
56 const Reference< XXMLSignatureTemplate >& aTemplate ,
57 const Reference< XSecurityEnvironment >& aEnvironment
58 ) throw( com::sun::star::xml::crypto::XMLSignatureException,
59 com::sun::star::uno::SecurityException )
61 xmlSecKeysMngrPtr pMngr = NULL ;
62 xmlSecDSigCtxPtr pDsigCtx = NULL ;
63 xmlNodePtr pNode = NULL ;
65 if( !aTemplate.is() )
66 throw RuntimeException() ;
68 if( !aEnvironment.is() )
69 throw RuntimeException() ;
71 //Get Keys Manager
72 Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
73 if( !xSecTunnel.is() ) {
74 throw RuntimeException() ;
77 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
78 if( pSecEnv == NULL )
79 throw RuntimeException() ;
81 //Get the xml node
82 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
83 if( !xElement.is() ) {
84 throw RuntimeException() ;
87 Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
88 if( !xNodTunnel.is() ) {
89 throw RuntimeException() ;
92 XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
93 if( pElement == NULL ) {
94 throw RuntimeException() ;
97 pNode = pElement->getNativeElement() ;
99 //Get the stream/URI binding
100 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
101 if( xUriBinding.is() ) {
102 //Register the stream input callbacks into libxml2
103 if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
104 throw RuntimeException() ;
107 setErrorRecorder( );
109 pMngr = pSecEnv->createKeysManager();
110 if( !pMngr ) {
111 throw RuntimeException() ;
114 //Create Signature context
115 pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
116 if( pDsigCtx == NULL )
118 //throw XMLSignatureException() ;
119 pSecEnv->destroyKeysManager( pMngr );
120 clearErrorRecorder();
121 return aTemplate;
124 //Sign the template
125 if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 )
127 if (pDsigCtx->status == xmlSecDSigStatusSucceeded)
128 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
129 else
130 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
132 else
134 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
138 xmlSecDSigCtxDestroy( pDsigCtx ) ;
139 pSecEnv->destroyKeysManager( pMngr );
141 //Unregistered the stream/URI binding
142 if( xUriBinding.is() )
143 xmlUnregisterStreamInputCallbacks() ;
145 clearErrorRecorder();
146 return aTemplate ;
149 /* XXMLSignature */
150 Reference< XXMLSignatureTemplate >
151 SAL_CALL XMLSignature_MSCryptImpl :: validate(
152 const Reference< XXMLSignatureTemplate >& aTemplate ,
153 const Reference< XXMLSecurityContext >& aSecurityCtx
154 ) throw( com::sun::star::uno::RuntimeException,
155 com::sun::star::uno::SecurityException,
156 com::sun::star::xml::crypto::XMLSignatureException ) {
157 xmlSecKeysMngrPtr pMngr = NULL ;
158 xmlSecDSigCtxPtr pDsigCtx = NULL ;
159 xmlNodePtr pNode = NULL ;
161 if( !aTemplate.is() )
162 throw RuntimeException() ;
164 if( !aSecurityCtx.is() )
165 throw RuntimeException() ;
167 //Get Keys Manager
168 Reference< XSecurityEnvironment > xSecEnv
169 = aSecurityCtx->getSecurityEnvironmentByIndex(
170 aSecurityCtx->getDefaultSecurityEnvironmentIndex());
171 Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ;
172 if( !xSecTunnel.is() ) {
173 throw RuntimeException() ;
176 SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ;
177 if( pSecEnv == NULL )
178 throw RuntimeException() ;
180 //Get the xml node
181 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
182 if( !xElement.is() )
183 throw RuntimeException() ;
185 Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
186 if( !xNodTunnel.is() ) {
187 throw RuntimeException() ;
190 XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
191 if( pElement == NULL )
192 throw RuntimeException() ;
194 pNode = pElement->getNativeElement() ;
196 //Get the stream/URI binding
197 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
198 if( xUriBinding.is() ) {
199 //Register the stream input callbacks into libxml2
200 if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
201 throw RuntimeException() ;
204 setErrorRecorder( );
206 pMngr = pSecEnv->createKeysManager();
207 if( !pMngr ) {
208 throw RuntimeException() ;
211 //Create Signature context
212 pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
213 if( pDsigCtx == NULL )
215 pSecEnv->destroyKeysManager( pMngr );
216 clearErrorRecorder();
217 return aTemplate;
220 //Verify signature
221 //The documentation says that the signature is only valid if the return value is 0 (that is, not < 0)
222 //AND pDsigCtx->status == xmlSecDSigStatusSucceeded. That is, we must not make any assumptions, if
223 //the return value is < 0. Then we must regard the signature as INVALID. We cannot use the
224 //error recorder feature to get the ONE error that made the verification fail, because there is no
225 //documentation/specification as to how to interpret the number of recorded errors and what is the initial
226 //error.
227 if( xmlSecDSigCtxVerify( pDsigCtx , pNode ) == 0 )
229 if (pDsigCtx->status == xmlSecDSigStatusSucceeded)
230 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
231 else
232 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
234 else
236 aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN);
239 xmlSecDSigCtxDestroy( pDsigCtx ) ;
240 pSecEnv->destroyKeysManager( pMngr );
242 //Unregistered the stream/URI binding
243 if( xUriBinding.is() )
244 xmlUnregisterStreamInputCallbacks() ;
247 clearErrorRecorder();
248 return aTemplate;
251 /* XServiceInfo */
252 OUString SAL_CALL XMLSignature_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
253 return impl_getImplementationName() ;
256 /* XServiceInfo */
257 sal_Bool SAL_CALL XMLSignature_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
258 Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
259 const OUString* pArray = seqServiceNames.getConstArray() ;
260 for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
261 if( *( pArray + i ) == serviceName )
262 return sal_True ;
264 return sal_False ;
267 /* XServiceInfo */
268 Sequence< OUString > SAL_CALL XMLSignature_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
269 return impl_getSupportedServiceNames() ;
272 //Helper for XServiceInfo
273 Sequence< OUString > XMLSignature_MSCryptImpl :: impl_getSupportedServiceNames() {
274 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
275 Sequence< OUString > seqServiceNames( 1 ) ;
276 seqServiceNames[0] = "com.sun.star.xml.crypto.XMLSignature";
277 return seqServiceNames ;
280 OUString XMLSignature_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
281 return OUString("com.sun.star.xml.security.bridge.xmlsec.XMLSignature_MSCryptImpl") ;
284 //Helper for registry
285 Reference< XInterface > SAL_CALL XMLSignature_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
286 return Reference< XInterface >( *new XMLSignature_MSCryptImpl( aServiceManager ) ) ;
289 Reference< XSingleServiceFactory > XMLSignature_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
290 return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */