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 
31 #include "signatureengine.hxx"
32 #include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp>
33 #include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 
36 namespace cssu = com::sun::star::uno;
37 namespace cssl = com::sun::star::lang;
38 namespace cssxc = com::sun::star::xml::crypto;
39 namespace cssxw = com::sun::star::xml::wrapper;
40 
41 #define SIGNATURE_TEMPLATE "com.sun.star.xml.crypto.XMLSignatureTemplate"
42 
43 #define	DECLARE_ASCII( SASCIIVALUE )																			\
44 	rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SASCIIVALUE ) )
45 
46 SignatureEngine::SignatureEngine( )
47 	:m_nTotalReferenceNumber(-1)
48 {
49 }
50 
51 bool SignatureEngine::checkReady() const
52 /****** SignatureEngine/checkReady *******************************************
53  *
54  *   NAME
55  *	checkReady -- checks the conditions for the main operation.
56  *
57  *   SYNOPSIS
58  *	bReady = checkReady( );
59  *
60  *   FUNCTION
61  *	checks whether all following conditions are satisfied:
62  *	1. the main operation has't begun yet;
63  *	2. the key material is known;
64  *	3. the amount of reference is known;
65  *	4. all of referenced elements, the key element and the signature
66  *	   template are bufferred.
67  *
68  *   INPUTS
69  *	empty
70  *
71  *   RESULT
72  *	bReady - true if all conditions are satisfied, false otherwise
73  *
74  *   HISTORY
75  *	05.01.2004 -	implemented
76  *
77  *   AUTHOR
78  *	Michael Mi
79  *	Email: michael.mi@sun.com
80  ******************************************************************************/
81 {
82 	bool rc = true;
83 
84 	sal_Int32 nKeyInc = 0;
85 	if (m_nIdOfKeyEC != 0)
86 	{
87 		nKeyInc = 1;
88 	}
89 
90 	if (m_bMissionDone ||
91 	    m_nIdOfKeyEC == -1 ||
92 	    m_nTotalReferenceNumber == -1 ||
93 	    m_nTotalReferenceNumber+1+nKeyInc > m_nNumOfResolvedReferences)
94 	{
95 		rc = false;
96 	}
97 
98 	return rc;
99 }
100 
101 void SignatureEngine::tryToPerform( )
102     	throw (cssu::Exception, cssu::RuntimeException)
103 /****** SignatureEngine/tryToPerform *****************************************
104  *
105  *   NAME
106  *	tryToPerform -- tries to perform the signature operation.
107  *
108  *   SYNOPSIS
109  *	tryToPerform( );
110  *
111  *   FUNCTION
112  *	if the situation is ready, perform following operations.
113  *	1. prepares a signature template;
114  *	2. calls the signature bridge component;
115  *	3. clears up all used resources;
116  *	4. notifies the result listener;
117  *	5. sets the "accomplishment" flag.
118  *
119  *   INPUTS
120  *	empty
121  *
122  *   RESULT
123  *	empty
124  *
125  *   HISTORY
126  *	05.01.2004 -	implemented
127  *
128  *   AUTHOR
129  *	Michael Mi
130  *	Email: michael.mi@sun.com
131  ******************************************************************************/
132 {
133 	if (checkReady())
134 	{
135 		const rtl::OUString ouSignatureTemplate (
136 			RTL_CONSTASCII_USTRINGPARAM( SIGNATURE_TEMPLATE ) );
137 		cssu::Reference < cssxc::XXMLSignatureTemplate >
138 			xSignatureTemplate( mxMSF->createInstance( ouSignatureTemplate ), cssu::UNO_QUERY );
139 
140 		OSL_ASSERT( xSignatureTemplate.is() );
141 
142 		cssu::Reference< cssxw::XXMLElementWrapper >
143 			xXMLElement = m_xSAXEventKeeper->getElement( m_nIdOfTemplateEC );
144 
145 		xSignatureTemplate->setTemplate(xXMLElement);
146 
147 		std::vector< sal_Int32 >::const_iterator ii = m_vReferenceIds.begin();
148 
149 		for( ; ii != m_vReferenceIds.end() ; ++ii )
150 		{
151 			xXMLElement = m_xSAXEventKeeper->getElement( *ii );
152 			xSignatureTemplate->setTarget(xXMLElement);
153 		}
154 
155 		/*
156 		 * set the Uri binding
157 		 */
158 		xSignatureTemplate->setBinding( this );
159 
160 		startEngine( xSignatureTemplate );
161 
162 		/*
163 		 * done
164 		 */
165 		clearUp( );
166 
167 		notifyResultListener();
168 
169 		m_bMissionDone = true;
170 	}
171 }
172 
173 void SignatureEngine::clearUp( ) const
174 /****** SignatureEngine/clearUp **********************************************
175  *
176  *   NAME
177  *	clearUp -- clear up all resources used by this operation.
178  *
179  *   SYNOPSIS
180  *	clearUp( );
181  *
182  *   FUNCTION
183  *	cleaning resources up includes:
184  *	1. releases the ElementCollector for the signature template element;
185  *	2. releases ElementCollectors for referenced elements;
186  *	3. releases the ElementCollector for the key element, if there is one.
187  *
188  *   INPUTS
189  *	empty
190  *
191  *   RESULT
192  *	empty
193  *
194  *   HISTORY
195  *	05.01.2004 -	implemented
196  *
197  *   AUTHOR
198  *	Michael Mi
199  *	Email: michael.mi@sun.com
200  ******************************************************************************/
201 {
202 	cssu::Reference < cssxc::sax::XReferenceResolvedBroadcaster >
203 		xReferenceResolvedBroadcaster( m_xSAXEventKeeper, cssu::UNO_QUERY );
204 	xReferenceResolvedBroadcaster->removeReferenceResolvedListener(
205 		m_nIdOfTemplateEC,
206 		(const cssu::Reference < cssxc::sax::XReferenceResolvedListener >)((SecurityEngine *)this));
207 
208 	m_xSAXEventKeeper->removeElementCollector(m_nIdOfTemplateEC);
209 
210 	std::vector< sal_Int32 >::const_iterator ii = m_vReferenceIds.begin();
211 
212 	for( ; ii != m_vReferenceIds.end() ; ++ii )
213 	{
214 		xReferenceResolvedBroadcaster->removeReferenceResolvedListener(
215 			*ii,
216 			(const cssu::Reference < cssxc::sax::XReferenceResolvedListener >)((SecurityEngine *)this));
217 		m_xSAXEventKeeper->removeElementCollector(*ii);
218 	}
219 
220 	if (m_nIdOfKeyEC != 0 && m_nIdOfKeyEC != -1)
221 	{
222 		m_xSAXEventKeeper->removeElementCollector(m_nIdOfKeyEC);
223 	}
224 }
225 
226 /* XReferenceCollector */
227 void SAL_CALL SignatureEngine::setReferenceCount( sal_Int32 count )
228 	throw (cssu::Exception, cssu::RuntimeException)
229 {
230 	m_nTotalReferenceNumber = count;
231 	tryToPerform();
232 }
233 
234 void SAL_CALL SignatureEngine::setReferenceId( sal_Int32 id )
235 	throw (cssu::Exception, cssu::RuntimeException)
236 {
237 	m_vReferenceIds.push_back( id );
238 }
239 
240 /* XUriBinding */
241 void SAL_CALL SignatureEngine::setUriBinding(
242 	const rtl::OUString& uri,
243 	const cssu::Reference< com::sun::star::io::XInputStream >& aInputStream )
244 	throw (cssu::Exception, cssu::RuntimeException)
245 {
246 	m_vUris.push_back(uri);
247 	m_vXInputStreams.push_back(aInputStream);
248 }
249 
250 cssu::Reference< com::sun::star::io::XInputStream > SAL_CALL SignatureEngine::getUriBinding( const rtl::OUString& uri )
251 	throw (cssu::Exception, cssu::RuntimeException)
252 {
253 	cssu::Reference< com::sun::star::io::XInputStream > xInputStream;
254 
255 	int size = m_vUris.size();
256 
257 	for( int i=0; i<size; ++i)
258 	{
259 		if (m_vUris[i] == uri)
260 		{
261 			xInputStream = m_vXInputStreams[i];
262 			break;
263 		}
264 	}
265 
266 	return xInputStream;
267 }
268 
269